diff --git a/.buildkite/hooks/pre-command b/.buildkite/hooks/pre-command index d3c2f7d0933..7f7df0f8f95 100755 --- a/.buildkite/hooks/pre-command +++ b/.buildkite/hooks/pre-command @@ -10,25 +10,8 @@ set -eo pipefail -retry() { - local retries=$1 - shift - - local count=0 - until "$@"; do - exit=$? - wait=$((2 ** count)) - count=$((count + 1)) - if [ $count -lt "$retries" ]; then - >&2 echo "Retry $count/$retries exited $exit, retrying in $wait seconds..." - sleep $wait - else - >&2 echo "Retry $count/$retries exited $exit, no more retries left." - return $exit - fi - done - return 0 -} +# shellcheck disable=SC1091 +source .buildkite/scripts/utils.sh get_os_details() { case $(uname | tr '[:upper:]' '[:lower:]') in diff --git a/.buildkite/package.yml b/.buildkite/package.yml index d50fde9b43e..8acce8119e1 100644 --- a/.buildkite/package.yml +++ b/.buildkite/package.yml @@ -5,52 +5,57 @@ notify: if: "build.state != 'passed'" env: - IMAGE_UBUNTU_X86_64: "family/core-ubuntu-2004" - IMAGE_UBUNTU_ARM_64: "core-ubuntu-2004-aarch64" + IMAGE_UBUNTU_X86_64: "family/core-ubuntu-2404" + IMAGE_UBUNTU_ARM_64: "core-ubuntu-2404-aarch64" GENERATE_WOLFI_IMAGES: true steps: - group: "Package" key: "package" steps: - - label: "Package Ubuntu-20 x86_64" + - label: "Package x86_64" key: "package-x86-64" - command: ".buildkite/scripts/package.sh {{matrix.type}}" + command: ".buildkite/scripts/package.sh {{matrix}}" agents: provider: "gcp" image: "${IMAGE_UBUNTU_X86_64}" machineType: "c2-standard-16" matrix: - setup: - type: - - "snapshot" - - "staging" + - "snapshot" + - "staging" artifact_paths: - "build/distributions/**/*" - "build/dependencies*.csv" + retry: + automatic: + - limit: 1 - - label: "Package Ubuntu-20 aarch64" + - label: "Package aarch64" key: "package-arm" - command: ".buildkite/scripts/package.sh {{matrix.type}}" + command: ".buildkite/scripts/package.sh {{matrix}}" agents: provider: "aws" imagePrefix: "${IMAGE_UBUNTU_ARM_64}" instanceType: "t4g.2xlarge" matrix: - setup: - type: - - "snapshot" - - "staging" + - "snapshot" + - "staging" artifact_paths: - "build/distributions/**/*" + retry: + automatic: + - limit: 1 - label: "DRA" key: "dra" - command: ".buildkite/scripts/dra.sh" + command: ".buildkite/scripts/dra.sh {{matrix}}" agents: provider: "gcp" image: "${IMAGE_UBUNTU_X86_64}" machineType: "c2-standard-16" + matrix: + - "snapshot" + - "staging" depends_on: - step: "package" allow_failure: false diff --git a/.buildkite/scripts/dra.sh b/.buildkite/scripts/dra.sh old mode 100644 new mode 100755 index 73559e6ddcd..8697cbdfa0d --- a/.buildkite/scripts/dra.sh +++ b/.buildkite/scripts/dra.sh @@ -10,8 +10,12 @@ set -eo pipefail -## Read current version. -VERSION=$(make get-version) +# Either staging or snapshot +TYPE="$1" + +# NOTE: load the shared functions +# shellcheck disable=SC1091 +source .buildkite/scripts/utils.sh echo "--- Restoring Artifacts" buildkite-agent artifact download "build/**/*" . @@ -31,48 +35,28 @@ fi # by default it uses the buildkite branch DRA_BRANCH="$BUILDKITE_BRANCH" # by default it publishes the DRA artifacts, for such it uses the collect command. -dra_command=collect +DRA_COMMAND=collect +VERSION=$(make get-version-only) BRANCHES_URL=https://storage.googleapis.com/artifacts-api/snapshots/branches.json curl -s "${BRANCHES_URL}" > active-branches.json -# as long as `8.x` is not in the active branches, we will explicitly add the condition. -if [ "$BUILDKITE_BRANCH" == "8.x" ] || grep -q "\"$BUILDKITE_BRANCH\"" active-branches.json ; then - echo "--- :arrow_right: Release Manager only supports the current active branches and 8.x, running" -else +if ! grep -q "\"$BUILDKITE_BRANCH\"" active-branches.json ; then # If no active branches are found, let's see if it is a feature branch. - echo "--- :arrow_right: Release Manager only supports the current active branches, skipping" - echo "BUILDKITE_BRANCH=$BUILDKITE_BRANCH" - echo "BUILDKITE_COMMIT=$BUILDKITE_COMMIT" - echo "VERSION=$VERSION" - echo "Supported branches:" - cat active-branches.json - if [[ $BUILDKITE_BRANCH =~ "feature/" ]]; then - buildkite-agent annotate "${BUILDKITE_BRANCH} will list DRA artifacts. Feature branches are not supported. Look for the supported branches in ${BRANCHES_URL}" --style 'info' --context 'ctx-info' - dra_command=list - - # use a different branch since DRA does not support feature branches but main/release branches - # for such we will use the VERSION and https://storage.googleapis.com/artifacts-api/snapshots/.json - # to know if the branch was branched out from main or the release branches. - MAJOR_MINOR=${VERSION%.*} - if curl -s "https://storage.googleapis.com/artifacts-api/snapshots/main.json" | grep -q "$VERSION" ; then - DRA_BRANCH=main - else - if curl -s "https://storage.googleapis.com/artifacts-api/snapshots/$MAJOR_MINOR.json" | grep -q "$VERSION" ; then - DRA_BRANCH="$MAJOR_MINOR" - else - buildkite-agent annotate "It was not possible to know the original base branch for ${BUILDKITE_BRANCH}. This won't fail - this is a feature branch." --style 'info' --context 'ctx-info-feature-branch' - exit 0 - fi - fi - else - buildkite-agent annotate "${BUILDKITE_BRANCH} is not supported yet. Look for the supported branches in ${BRANCHES_URL}" --style 'warning' --context 'ctx-warn' - exit 1 - fi + dra_process_other_branches fi +echo "--- :arrow_right: Release Manager only supports the current active branches" +echo "BUILDKITE_BRANCH=$BUILDKITE_BRANCH" +echo "BUILDKITE_COMMIT=$BUILDKITE_COMMIT" +echo "VERSION=$VERSION" +echo "Supported branches:" +cat active-branches.json + dra() { local workflow=$1 local command=$2 + local qualifier=${3:-""} echo "--- Run release manager $workflow (DRA command: $command)" + set -x docker run --rm \ --name release-manager \ -e VAULT_ADDR="${VAULT_ADDR_SECRET}" \ @@ -86,23 +70,23 @@ dra() { --commit $BUILDKITE_COMMIT \ --workflow $workflow \ --artifact-set main \ + --qualifier "$qualifier" \ --version $VERSION | tee rm-output.txt + set +x - # Create Buildkite annotation similarly done in Beats: - # https://github.com/elastic/beats/blob/90f9e8f6e48e76a83331f64f6c8c633ae6b31661/.buildkite/scripts/dra.sh#L74-L81 - if [[ "$command" == "collect" ]]; then - # extract the summary URL from a release manager output line like: - # Report summary-18.22.0.html can be found at https://artifacts-staging.elastic.co/apm-server/18.22.0-ABCDEFGH/summary-18.22.0.html - SUMMARY_URL=$(grep -E '^Report summary-.* can be found at ' rm-output.txt | grep -oP 'https://\S+' | awk '{print $1}') - rm rm-output.txt + create_annotation_dra_summary "$command" "$workflow" rm-output.txt +} - # and make it easily clickable as a Builkite annotation - printf "**${workflow} summary link:** [${SUMMARY_URL}](${SUMMARY_URL})\n" | buildkite-agent annotate --style=success --append +if [[ "${TYPE}" == "staging" ]]; then + qualifier=$(fetch_elastic_qualifier "$DRA_BRANCH") + # TODO: main and 8.x are not needed to run the DRA for staging + # but main is needed until we do alpha1 releases of 9.0.0 + if [[ "${DRA_BRANCH}" != "8.x" ]]; then + dra "${TYPE}" "$DRA_COMMAND" "${qualifier}" fi -} +fi -dra "snapshot" "$dra_command" -if [[ "${DRA_BRANCH}" != "main" && "${DRA_BRANCH}" != "8.x" ]]; then - echo "DRA_BRANCH is neither 'main' nor '8.x'" - dra "staging" "$dra_command" +if [[ "${TYPE}" == "snapshot" ]]; then + # NOTE: qualifier is not needed for snapshots, let's unset it. + dra "${TYPE}" "$DRA_COMMAND" "" fi diff --git a/.buildkite/scripts/package.sh b/.buildkite/scripts/package.sh index 2c396c057b2..691c399a820 100755 --- a/.buildkite/scripts/package.sh +++ b/.buildkite/scripts/package.sh @@ -19,6 +19,17 @@ if [[ ${TYPE} == "snapshot" ]]; then MAKE_GOAL="${MAKE_GOAL}-snapshot" fi +if [[ ${TYPE} == "staging" ]]; then + echo "--- Prepare the Elastic Qualifier" + # NOTE: load the shared functions + # shellcheck disable=SC1091 + source .buildkite/scripts/utils.sh + dra_process_other_branches + ELASTIC_QUALIFIER=$(fetch_elastic_qualifier "$DRA_BRANCH") + export ELASTIC_QUALIFIER +fi + +echo "--- Run $MAKE_GOAL for $DRA_BRANCH" make $MAKE_GOAL ls -l build/distributions/ diff --git a/.buildkite/scripts/utils.sh b/.buildkite/scripts/utils.sh new file mode 100644 index 00000000000..762495f2ae8 --- /dev/null +++ b/.buildkite/scripts/utils.sh @@ -0,0 +1,80 @@ +# An opinionated approach to manage the Elatic Qualifier for the DRA in a Google Bucket +# Instead of using the ELASTIC_QUALIFIER env variable. +fetch_elastic_qualifier() { + local branch=$1 + qualifier="" + URL="https://storage.googleapis.com/dra-qualifier/$branch" + if curl -sf -o /dev/null "$URL" ; then + qualifier=$(curl -s "$URL") + fi + echo "$qualifier" +} + +retry() { + local retries=$1 + shift + + local count=0 + until "$@"; do + exit=$? + wait=$((2 ** count)) + count=$((count + 1)) + if [ $count -lt "$retries" ]; then + >&2 echo "Retry $count/$retries exited $exit, retrying in $wait seconds..." + sleep $wait + else + >&2 echo "Retry $count/$retries exited $exit, no more retries left." + return $exit + fi + done + return 0 +} + +# +# An opinionated approach to detect if unsupported Unified Release branches +# can be used, this is handy for testing feature branches in dry-run mode +# It produces the below environment variables: +# - VERSION +# - DRA_COMMAND +# - DRA_BRANCH +dra_process_other_branches() { + ## Read current version without the qualifier + VERSION=$(make get-version-only) + DRA_BRANCH="$BUILDKITE_BRANCH" + if [[ $BUILDKITE_BRANCH =~ "feature/" ]]; then + buildkite-agent annotate "${BUILDKITE_BRANCH} will list DRA artifacts. Feature branches are not supported. Look for the supported branches in ${BRANCHES_URL}" --style 'info' --context 'ctx-info' + DRA_COMMAND=list + + # use a different branch since DRA does not support feature branches but main/release branches + # for such we will use the VERSION and https://storage.googleapis.com/artifacts-api/snapshots/.json + # to know if the branch was branched out from main or the release branches. + MAJOR_MINOR=${VERSION%.*} + if curl -s "https://storage.googleapis.com/artifacts-api/snapshots/main.json" | grep -q "$VERSION" ; then + DRA_BRANCH=main + else + if curl -s "https://storage.googleapis.com/artifacts-api/snapshots/$MAJOR_MINOR.json" | grep -q "$VERSION" ; then + DRA_BRANCH="$MAJOR_MINOR" + else + buildkite-agent annotate "It was not possible to know the original base branch for ${BUILDKITE_BRANCH}. This won't fail - this is a feature branch." --style 'info' --context 'ctx-info-feature-branch' + fi + fi + fi + export DRA_BRANCH DRA_COMMAND VERSION +} + +# Create Buildkite annotation similarly done in Beats: +# https://github.com/elastic/beats/blob/90f9e8f6e48e76a83331f64f6c8c633ae6b31661/.buildkite/scripts/dra.sh#L74-L81 +create_annotation_dra_summary() { + local command=$1 + local workflow=$2 + local output=$3 + if [[ "$command" == "collect" ]]; then + # extract the summary URL from a release manager output line like: + # Report summary-18.22.0.html can be found at https://artifacts-staging.elastic.co/apm-server/18.22.0-ABCDEFGH/summary-18.22.0.html + SUMMARY_URL=$(grep -E '^Report summary-.* can be found at ' "$output" | grep -oP 'https://\S+' | awk '{print $1}') + rm "$output" + + # and make it easily clickable as a Builkite annotation + printf "**${workflow} summary link:** [${SUMMARY_URL}](${SUMMARY_URL})\n" | buildkite-agent annotate --style=success --append + fi +} diff --git a/.ci/scripts/bench.sh b/.ci/scripts/bench.sh index 15f9c72c42a..5b1a379b556 100755 --- a/.ci/scripts/bench.sh +++ b/.ci/scripts/bench.sh @@ -125,6 +125,28 @@ function buildkite::download_last_artifact { BUILDKITE_DOWNLOAD_URL="${download_url}" buildkite::req_download_artifact } +####################################### +# Retry n number of times the given command +function retry() { + local retries=$1 + shift + + local count=0 + until "$@"; do + exit=$? + wait=$((2 ** count)) + count=$((count + 1)) + if [ $count -lt "$retries" ]; then + >&2 echo "Retry $count/$retries exited $exit, retrying in $wait seconds..." + sleep $wait + else + >&2 echo "Retry $count/$retries exited $exit, no more retries left." + return $exit + fi + done + return 0 +} + ## Buildkite specific configuration if [ "${CI}" == "true" ] ; then # If HOME is not set then use the Buildkite workspace @@ -147,17 +169,20 @@ if [ "${CI}" == "true" ] ; then [ -z "${REPO}" ] && echo "Environment variable 'REPO' must be defined" && exit 1; export BUILDKITE_TOKEN="${BUILDKITE_TOKEN_SECRET}" + echo "--- Setting up the :golang: environment..." + GO_VERSION=$(cat .go-version) + OS_NAME=linux + OS_ARCH=amd64 + retry 5 curl -sL -o "${BASE_PROJECT}"/gvm "https://github.com/andrewkroh/gvm/releases/download/v0.5.2/gvm-${OS_NAME}-${OS_ARCH}" + chmod +x "${BASE_PROJECT}"/gvm + retry 5 "${BASE_PROJECT}"/gvm install "$GO_VERSION" + eval "$("${BASE_PROJECT}"/gvm use "$GO_VERSION")" + echo "Golang version:" + go version + GOPATH=$(command go env GOPATH) # Redirect go env to current dir - export GOROOT="${BASE_PROJECT}/.go" - export GOPATH="${BASE_PROJECT}/go" export PATH="${GOPATH}/bin:${PATH}" - # Install g (go version manager) - curl -sSL https://git.io/g-install | bash -s -- -y - - # Install specific version - g install $(cat .go-version) - # Make sure gomod can be deleted automatically as part of the CI function teardown { local arg=${?} diff --git a/.ci/scripts/download-png-from-kibana.sh b/.ci/scripts/download-png-from-kibana.sh index c6dc99641e1..c9d795d1218 100755 --- a/.ci/scripts/download-png-from-kibana.sh +++ b/.ci/scripts/download-png-from-kibana.sh @@ -35,7 +35,7 @@ JOB_PARAMS=$(echo " " | tr -d "[:space:]") -png_url_path=$(curl -XPOST -v -L -u "$kibana_user:$kibana_pwd" -H 'kbn-xsrf: true' --data-urlencode "jobParams=${JOB_PARAMS}" $kibana_host/api/reporting/generate/pngV2 | jq -r '.path') +png_url_path=$(curl -L -u "$kibana_user:$kibana_pwd" -H 'kbn-xsrf: true' --data-urlencode "jobParams=${JOB_PARAMS}" $kibana_host/api/reporting/generate/pngV2 | jq -r '.path') if [[ "$png_url_path" == "null" ]] then diff --git a/.ci/updatecli/bump-golang.yml b/.ci/updatecli/bump-golang.yml index a8d9abc9716..57b20accc83 100644 --- a/.ci/updatecli/bump-golang.yml +++ b/.ci/updatecli/bump-golang.yml @@ -106,7 +106,6 @@ targets: files: - go.mod - cmd/intake-receiver/go.mod - - internal/glog/go.mod - systemtest/go.mod - tools/go.mod matchpattern: 'go \d+.\d+' diff --git a/.github/workflows/benchmarks.yml b/.github/workflows/benchmarks.yml index 799cbcd1800..c0d7214a36c 100644 --- a/.github/workflows/benchmarks.yml +++ b/.github/workflows/benchmarks.yml @@ -8,6 +8,16 @@ on: required: false type: boolean default: false + enableTailSampling: + description: 'Enable tail-based sampling on the APM server' + required: false + type: boolean + default: false + tailSamplingStorageLimit: + description: 'Storage size limit of tail-based sampling on the APM server, defaults to 10GB' + required: false + type: string + default: "10GB" profile: description: 'The system profile used to run the benchmarks' required: false @@ -25,9 +35,14 @@ on: description: 'Set the expression that matches the benchmark scenarios to run' required: false type: string + pgoExport: + description: 'Run the benchmarks with PGO export' + required: false + type: boolean + default: false schedule: - cron: '0 17 * * *' # Scheduled regular benchmarks. - - cron: '0 5 */5 * *' # Scheduled PGO benchmarks. + - cron: '0 0 1 * *' # Scheduled PGO benchmarks. env: PNG_REPORT_FILE: out.png @@ -51,12 +66,16 @@ jobs: SSH_KEY: ./id_rsa_terraform TF_VAR_private_key: ./id_rsa_terraform TF_VAR_public_key: ./id_rsa_terraform.pub - RUN_STANDALONE: ${{ inputs.runStandalone || github.event.schedule=='0 5 */5 * *' }} + TF_VAR_run_standalone: ${{ inputs.runStandalone || github.event.schedule=='0 0 1 * *' }} + TF_VAR_apm_server_tail_sampling: ${{ inputs.enableTailSampling || 'false' }} # set the default again otherwise schedules won't work + TF_VAR_apm_server_tail_sampling_storage_limit: ${{ inputs.tailSamplingStorageLimit || '10GB' }} # set the default again otherwise schedules won't work + RUN_STANDALONE: ${{ inputs.runStandalone || github.event.schedule=='0 0 1 * *' }} + PGO_EXPORT: ${{ inputs.pgoExport || github.event.schedule=='0 0 1 * *' }} TFVARS_SOURCE: ${{ inputs.profile || 'system-profiles/8GBx1zone.tfvars' }} # // Default to use an 8gb profile TF_VAR_BUILD_ID: ${{ github.run_id }} TF_VAR_ENVIRONMENT: ci TF_VAR_REPO: ${{ github.repository }} - GOBENCH_TAGS: branch=${{ github.head_ref || github.ref }},commit=${{ github.sha }},target_branch=${{ github.base_ref }} + GOBENCH_TAGS: branch=${{ github.head_ref || github.ref }},commit=${{ github.sha }},target_branch=${{ github.base_ref }},enable_tail_sampling=${{ inputs.enableTailSampling }} GOBENCH_PASSWORD: ${{ secrets.GOBENCH_PASSWORD }} GOBENCH_USERNAME: ${{ secrets.GOBENCH_USERNAME }} GOBENCH_HOST: ${{ secrets.GOBENCH_HOST }} @@ -67,7 +86,7 @@ jobs: with: go-version-file: 'go.mod' - - uses: rlespinasse/github-slug-action@797d68864753cbceedc271349d402da4590e6302 + - uses: rlespinasse/github-slug-action@aba9f8db6ef36e0733227a62673d6592b1f430ea - name: Set up env run: | @@ -91,14 +110,13 @@ jobs: username: ${{ secrets.ELASTIC_DOCKER_USERNAME }} password: ${{ secrets.ELASTIC_DOCKER_PASSWORD }} - - uses: elastic/oblt-actions/google/auth@v1 - uses: elastic/oblt-actions/aws/auth@v1 with: - role-duration-seconds: 18000 # 5 hours + role-duration-seconds: 21600 # 6 hours - - uses: google-github-actions/get-secretmanager-secrets@95a0b09b8348ef3d02c68c6ba5662a037e78d713 # v2.1.4 + - uses: google-github-actions/get-secretmanager-secrets@e5bb06c2ca53b244f978d33348d18317a7f263ce # v2.2.2 with: export_to_environment: true secrets: |- @@ -106,7 +124,7 @@ jobs: - uses: hashicorp/setup-terraform@v3 with: - terraform_version: 1.3.7 + terraform_version: ~1.10.0 terraform_wrapper: false - name: Init terraform module @@ -133,10 +151,6 @@ jobs: admin_console_url=$(terraform output -raw admin_console_url) echo "admin_console_url=$admin_console_url" >> "$GITHUB_OUTPUT" echo "-> infra setup done" - env: - TF_VAR_worker_region: ${{ env.AWS_REGION }} - TF_VAR_run_standalone: ${{ env.RUN_STANDALONE }} - - name: Run benchmarks autotuned if: ${{ inputs.benchmarkAgents == '' }} run: make run-benchmark-autotuned @@ -189,7 +203,7 @@ jobs: - name: Copy CPU profile run: make cp-cpuprof - + - name: Upload CPU profile uses: actions/upload-artifact@v4 with: @@ -218,7 +232,7 @@ jobs: github-token: ${{ steps.get_token.outputs.token }} - name: Import GPG key - uses: crazy-max/ghaction-import-gpg@01dd5d3ca463c7f10f7f4f7b4f177225ac661ee4 # v6.1.0 + uses: crazy-max/ghaction-import-gpg@cb9bde2e2525e640591a934b1fd28eef1dcaf5e5 # v6.2.0 with: gpg_private_key: ${{ secrets.APM_SERVER_RELEASE_GPG_PRIVATE_KEY }} passphrase: ${{ secrets.APM_SERVER_RELEASE_PASSPHRASE }} @@ -226,7 +240,7 @@ jobs: git_commit_gpgsign: true - name: Open PGO PR - if: ${{ env.RUN_STANDALONE == 'true' }} + if: ${{ env.PGO_EXPORT == 'true' }} run: ${{ github.workspace }}/.ci/scripts/push-pgo-pr.sh env: WORKSPACE_PATH: ${{ github.workspace }} @@ -234,6 +248,17 @@ jobs: GITHUB_TOKEN: ${{ steps.get_token.outputs.token }} WORKFLOW: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}/attempts/${{ github.run_attempt }} + # Secrets are rotated daily, if the benchmarks run between the rotation window, then + # there is a high chance things will stop working + # This is trying to reduce the chances of that happening. + # See https://github.com/elastic/observability-test-environments/actions/workflows/cluster-rotate-api-keys.yml + - uses: google-github-actions/get-secretmanager-secrets@e5bb06c2ca53b244f978d33348d18317a7f263ce # v2.2.2 + if: always() + with: + export_to_environment: true + secrets: |- + EC_API_KEY:elastic-observability/elastic-cloud-observability-team-pro-api-key + - name: Tear down benchmark environment if: always() run: make init destroy @@ -248,13 +273,14 @@ jobs: # Notify result to Slack only on schedule (nightly run) - if: github.event_name == 'schedule' - uses: slackapi/slack-github-action@37ebaef184d7626c5f204ab8d3baff4262dd30f0 # v1.27.0 - env: - SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} + uses: slackapi/slack-github-action@485a9d42d3a73031f12ec201c457e2162c45d02d # v2.0.0 with: - channel-id: "#apm-server" + method: chat.postMessage + token: ${{ secrets.SLACK_BOT_TOKEN }} payload: | { + "channel": "#apm-server", + "text": "${{ github.event_name == 'schedule' && 'Nightly' || '' }} APM Server benchmarks succesfully executed!", "blocks": [ { "type": "section", diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4b5914a6b44..6a3edf865df 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -123,7 +123,7 @@ jobs: - uses: actions/checkout@v4 - name: Get changed files id: changed-files - uses: tj-actions/changed-files@c3a1bb2c992d77180ae65be6ae6c166cf40f857c # v45.0.3 + uses: tj-actions/changed-files@d6e91a2266cdb9d62096cebf1e8546899c6aa18f # v45.0.6 with: files: .go-version diff --git a/.github/workflows/functional-tests.yml b/.github/workflows/functional-tests.yml new file mode 100644 index 00000000000..17ee4f4edbb --- /dev/null +++ b/.github/workflows/functional-tests.yml @@ -0,0 +1,66 @@ +--- +name: functional-tests + +on: + workflow_dispatch: ~ + schedule: + - cron: '0 3 * * 1-5' + +permissions: + contents: read + id-token: write + +env: + TF_VAR_BRANCH: ${{ github.ref_name }} + TF_VAR_BUILD_ID: ${{ github.run_id }} + TF_VAR_ENVIRONMENT: 'ci' + TF_VAR_REPO: ${{ github.repository }} + TERRAFORM_VERSION: 1.10.2 + +jobs: + run: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + environment: + - 'qa' + - 'pro' + steps: + - uses: actions/checkout@v4 + + - uses: hashicorp/setup-terraform@b9cd54a3c349d3f38e8881555d616ced269862dd # v3.1.2 + with: + terraform_version: "${{ env.TERRAFORM_VERSION }}" + + - uses: actions/setup-go@v5 + with: + go-version-file: 'functionaltests/go.mod' + + - uses: elastic/oblt-actions/google/auth@v1 + + - uses: google-github-actions/get-secretmanager-secrets@e5bb06c2ca53b244f978d33348d18317a7f263ce # v2.2.2 + with: + export_to_environment: true + secrets: |- + EC_API_KEY:elastic-observability/elastic-cloud-observability-team-${{ matrix.environment }}-api-key + + - run: | + export TF_VAR_CREATED_DATE=$(date +%s) + cd functionaltests && go test -v -timeout=30m -target "${{ matrix.environment }}" ./ + + notify: + if: always() + runs-on: ubuntu-latest + needs: + - run + steps: + - id: check + uses: elastic/oblt-actions/check-dependent-jobs@v1 + with: + jobs: ${{ toJSON(needs) }} + - uses: elastic/oblt-actions/slack/notify-result@v1 + with: + bot-token: ${{ secrets.SLACK_BOT_TOKEN }} + channel-id: "#apm-server" + status: ${{ steps.check.outputs.status }} diff --git a/.github/workflows/mergify-labels-copier.yml b/.github/workflows/mergify-labels-copier.yml new file mode 100644 index 00000000000..d5ff3ed0e48 --- /dev/null +++ b/.github/workflows/mergify-labels-copier.yml @@ -0,0 +1,23 @@ +name: mergify backport labels copier + +on: + pull_request: + types: + - opened + +permissions: + contents: read + +jobs: + mergify-backport-labels-copier: + runs-on: ubuntu-latest + if: startsWith(github.head_ref, 'mergify/bp/') + permissions: + # Add GH labels + pull-requests: write + # See https://github.com/cli/cli/issues/6274 + repository-projects: read + steps: + - uses: elastic/oblt-actions/mergify/labels-copier@v1 + with: + excluded-labels-regex: "^backport-*" diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml new file mode 100644 index 00000000000..a4c3f04ec23 --- /dev/null +++ b/.github/workflows/pre-commit.yml @@ -0,0 +1,19 @@ +name: pre-commit + +on: + pull_request: + push: + branches: + - main + - 7.* + - 8.* + - 9.* + +permissions: + contents: read + +jobs: + pre-commit: + runs-on: ubuntu-latest + steps: + - uses: elastic/oblt-actions/pre-commit@v1 diff --git a/.github/workflows/prepare-release/action.yml b/.github/workflows/prepare-release/action.yml index ef312a3e038..6cb48c188b5 100644 --- a/.github/workflows/prepare-release/action.yml +++ b/.github/workflows/prepare-release/action.yml @@ -49,6 +49,14 @@ runs: VERSION: ${{ inputs.version }} shell: 'bash' + - name: validate version format (major only) + if: ${{ inputs.type == 'major' && ! endsWith(inputs.version, '.0.0') }} + run: |- + FAILURE_MESSAGE='version is not a major one but a patch (only support for .0.0)' + echo "FAILURE_MESSAGE=${FAILURE_MESSAGE}" >> "$GITHUB_ENV" + echo "::error::${FAILURE_MESSAGE}" ; exit 1 + shell: 'bash' + - name: validate version format (minor only) if: ${{ inputs.type == 'minor' && ! endsWith(inputs.version, '0') }} run: |- @@ -65,6 +73,18 @@ runs: echo "::error::${FAILURE_MESSAGE}" ; exit 1 shell: 'bash' + - name: validate if branch already exists (major only) + if: ${{ inputs.type == 'major' }} + run: |- + if git ls-remote --exit-code --heads "https://github.com/${GITHUB_REPOSITORY}.git" "$BRANCH" > /dev/null ; then + echo "FAILURE_MESSAGE=${FAILURE_MESSAGE}" >> "$GITHUB_ENV" + echo "::error::${FAILURE_MESSAGE}" ; exit 1 + fi + shell: 'bash' + env: + BRANCH: ${{ steps.generate.outputs.release-branch }} + FAILURE_MESSAGE: Branch already exists. This is not a major release. + - name: validate if branch already exists (minor only) if: ${{ inputs.type == 'minor' }} run: |- diff --git a/.github/workflows/run-major-release.yml b/.github/workflows/run-major-release.yml new file mode 100644 index 00000000000..016e870b08a --- /dev/null +++ b/.github/workflows/run-major-release.yml @@ -0,0 +1,114 @@ +--- +name: run-major-release + +on: + workflow_dispatch: + inputs: + version: + description: 'The new version to be set, normally the version in the main branch (semver format: major.0.0)' + required: true + type: string + +# Avoid concurrency so we can watch the releases correctly +concurrency: + group: ${{ github.workflow }} + +permissions: + contents: read + +env: + JOB_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} + SLACK_CHANNEL: "#apm-server" + +jobs: + prepare: + runs-on: ubuntu-latest + outputs: + release-branch: ${{ steps.prepare.outputs.release-branch }} + release-type: ${{ steps.prepare.outputs.release-type }} + release-version: ${{ steps.prepare.outputs.release-version }} + slack-thread: ${{ steps.prepare.outputs.slack-thread }} + steps: + - uses: actions/checkout@v4 + - id: prepare + uses: ./.github/workflows/prepare-release + with: + slack-bot-token: ${{ secrets.SLACK_BOT_TOKEN }} + version: ${{ inputs.version }} + type: 'major' + + run-major: + runs-on: ubuntu-latest + needs: [ prepare ] + env: + RELEASE_BRANCH: ${{ needs.prepare.outputs.release-branch }} + RELEASE_TYPE: ${{ needs.prepare.outputs.release-type }} + RELEASE_VERSION: ${{ needs.prepare.outputs.release-version }} + permissions: + contents: write + steps: + + - uses: elastic/oblt-actions/slack/send@v1 + with: + bot-token: ${{ secrets.SLACK_BOT_TOKEN }} + channel-id: ${{ env.SLACK_CHANNEL }} + message: |- + Feature freeze for `${{ github.repository }}@${{ env.RELEASE_VERSION }}` just started. + The `${{ github.repository }}@${{ env.RELEASE_BRANCH }}` branch will be created Today. + thread-timestamp: ${{ needs.prepare.outputs.slack-thread || '' }} + + - name: Get token + id: get_token + uses: tibdex/github-app-token@3beb63f4bd073e61482598c45c71c1019b59b73a # v2.1.0 + with: + app_id: ${{ secrets.OBS_AUTOMATION_APP_ID }} + private_key: ${{ secrets.OBS_AUTOMATION_APP_PEM }} + permissions: >- + { + "contents": "write", + "pull_requests": "write" + } + + - uses: actions/checkout@v4 + with: + # 0 indicates all history for all branches and tags. + fetch-depth: 0 + + # Required to use a service account, otherwise PRs created by + # GitHub bot won't trigger any CI builds. + # See https://github.com/peter-evans/create-pull-request/issues/48#issuecomment-537478081 + - name: Configure git user + uses: elastic/oblt-actions/git/setup@v1 + with: + github-token: ${{ steps.get_token.outputs.token }} + + - name: Import GPG key + uses: crazy-max/ghaction-import-gpg@cb9bde2e2525e640591a934b1fd28eef1dcaf5e5 # v6.2.0 + with: + gpg_private_key: ${{ secrets.APM_SERVER_RELEASE_GPG_PRIVATE_KEY }} + passphrase: ${{ secrets.APM_SERVER_RELEASE_PASSPHRASE }} + git_user_signingkey: true + git_commit_gpgsign: true + + - run: make major-release + env: + GH_TOKEN: ${{ steps.get_token.outputs.token }} + + - if: success() + uses: elastic/oblt-actions/slack/send@v1 + with: + bot-token: ${{ secrets.SLACK_BOT_TOKEN }} + channel-id: ${{ env.SLACK_CHANNEL }} + message: |- + `${{ github.repository }}@${{ env.RELEASE_BRANCH }}` is now available. + The docs and other references are updated. You can start using it. + thread-timestamp: ${{ needs.prepare.outputs.slack-thread || '' }} + + - if: failure() + uses: elastic/oblt-actions/slack/send@v1 + with: + bot-token: ${{ secrets.SLACK_BOT_TOKEN }} + channel-id: ${{ env.SLACK_CHANNEL }} + message: |- + :fire: Something went wrong with the release. See <${{ env.JOB_URL }}|logs>. + thread-timestamp: ${{ needs.prepare.outputs.slack-thread || '' }} diff --git a/.github/workflows/run-minor-release.yml b/.github/workflows/run-minor-release.yml index 76c0dcaf567..9776fea8185 100644 --- a/.github/workflows/run-minor-release.yml +++ b/.github/workflows/run-minor-release.yml @@ -83,7 +83,7 @@ jobs: github-token: ${{ steps.get_token.outputs.token }} - name: Import GPG key - uses: crazy-max/ghaction-import-gpg@01dd5d3ca463c7f10f7f4f7b4f177225ac661ee4 # v6.1.0 + uses: crazy-max/ghaction-import-gpg@cb9bde2e2525e640591a934b1fd28eef1dcaf5e5 # v6.2.0 with: gpg_private_key: ${{ secrets.APM_SERVER_RELEASE_GPG_PRIVATE_KEY }} passphrase: ${{ secrets.APM_SERVER_RELEASE_PASSPHRASE }} diff --git a/.github/workflows/run-patch-release.yml b/.github/workflows/run-patch-release.yml index f7392557281..4afe520578a 100644 --- a/.github/workflows/run-patch-release.yml +++ b/.github/workflows/run-patch-release.yml @@ -76,7 +76,7 @@ jobs: github-token: ${{ steps.get_token.outputs.token }} - name: Import GPG key - uses: crazy-max/ghaction-import-gpg@01dd5d3ca463c7f10f7f4f7b4f177225ac661ee4 # v6.1.0 + uses: crazy-max/ghaction-import-gpg@cb9bde2e2525e640591a934b1fd28eef1dcaf5e5 # v6.2.0 with: gpg_private_key: ${{ secrets.APM_SERVER_RELEASE_GPG_PRIVATE_KEY }} passphrase: ${{ secrets.APM_SERVER_RELEASE_PASSPHRASE }} diff --git a/.github/workflows/smoke-tests-ess.yml b/.github/workflows/smoke-tests-ess.yml index 609b32b1a1f..6ee49bdc044 100644 --- a/.github/workflows/smoke-tests-ess.yml +++ b/.github/workflows/smoke-tests-ess.yml @@ -57,6 +57,10 @@ jobs: - uses: actions/checkout@v4 with: ref: ${{ inputs.branch }} + - uses: hashicorp/setup-terraform@v3 + with: + terraform_version: ~1.10.0 + terraform_wrapper: false - name: Setup cluster env uses: ./.github/workflows/setup-cluster-env @@ -64,7 +68,7 @@ jobs: - uses: elastic/oblt-actions/google/auth@v1 - - uses: google-github-actions/get-secretmanager-secrets@95a0b09b8348ef3d02c68c6ba5662a037e78d713 # v2.1.4 + - uses: google-github-actions/get-secretmanager-secrets@e5bb06c2ca53b244f978d33348d18317a7f263ce # v2.2.2 with: export_to_environment: true secrets: |- @@ -72,6 +76,18 @@ jobs: - name: Run smoke tests ${{ matrix.test }} for ${{ matrix.version }} run: make smoketest/run-version TEST_DIR=${{ matrix.test }} SMOKETEST_VERSION=${{ matrix.version }} + + # Secrets are rotated daily, if the benchmarks run between the rotation window, then + # there is a high chance things will stop working + # This is trying to reduce the chances of that happening. + # See https://github.com/elastic/observability-test-environments/actions/workflows/cluster-rotate-api-keys.yml + - uses: google-github-actions/get-secretmanager-secrets@e5bb06c2ca53b244f978d33348d18317a7f263ce # v2.2.2 + if: always() + with: + export_to_environment: true + secrets: |- + EC_API_KEY:elastic-observability/elastic-cloud-observability-team-pro-api-key + - if: always() name: Teardown smoke test infra run: make smoketest/cleanup TEST_DIR=${{ matrix.test }} diff --git a/.github/workflows/smoke-tests-os.yml b/.github/workflows/smoke-tests-os.yml index 4560233919f..a0b3ba20a0a 100644 --- a/.github/workflows/smoke-tests-os.yml +++ b/.github/workflows/smoke-tests-os.yml @@ -50,6 +50,10 @@ jobs: - uses: actions/checkout@v4 with: ref: ${{ inputs.branch }} + - uses: hashicorp/setup-terraform@v3 + with: + terraform_version: ~1.10.0 + terraform_wrapper: false - name: Get version run: echo "VERSION=$(make get-version)" >> "${GITHUB_ENV}" - name: Setup cluster env @@ -59,7 +63,7 @@ jobs: - uses: elastic/oblt-actions/google/auth@v1 - - uses: google-github-actions/get-secretmanager-secrets@95a0b09b8348ef3d02c68c6ba5662a037e78d713 # v2.1.4 + - uses: google-github-actions/get-secretmanager-secrets@e5bb06c2ca53b244f978d33348d18317a7f263ce # v2.2.2 with: export_to_environment: true secrets: |- diff --git a/.go-version b/.go-version index 14bee92c9e7..ca8ec414e78 100644 --- a/.go-version +++ b/.go-version @@ -1 +1 @@ -1.23.2 +1.23.5 diff --git a/.mergify.yml b/.mergify.yml index b6f2ee940fc..7717033e3e5 100644 --- a/.mergify.yml +++ b/.mergify.yml @@ -389,3 +389,31 @@ pull_request_rules: labels: - "backport" title: "[{{ destination_branch }}] {{ title }} (backport #{{ number }})" + - name: backport patches to 8.16 branch + conditions: + - merged + - base=main + - label=backport-8.16 + actions: + backport: + assignees: + - "{{ author }}" + branches: + - "8.16" + labels: + - "backport" + title: "[{{ destination_branch }}] {{ title }} (backport #{{ number }})" + - name: backport patches to 8.17 branch + conditions: + - merged + - base=main + - label=backport-8.17 + actions: + backport: + assignees: + - "{{ author }}" + branches: + - "8.17" + labels: + - "backport" + title: "[{{ destination_branch }}] {{ title }} (backport #{{ number }})" diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 00000000000..f8572ce7c4e --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,9 @@ +repos: +- repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.6.0 + hooks: + - id: check-executables-have-shebangs + - id: check-shebang-scripts-are-executable + exclude: (.*/.*.(tmpl|tftpl)$) + - id: check-merge-conflict + args: ['--assume-in-merge'] diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc index dffd289c9bc..16b1fc41989 100644 --- a/CHANGELOG.asciidoc +++ b/CHANGELOG.asciidoc @@ -1,4 +1,6 @@ // tag::list[] +* <> +* <> * <> * <> * <> @@ -19,6 +21,8 @@ // tag::includes[] include::./changelogs/head.asciidoc[] +include::./changelogs/8.17.asciidoc[] +include::./changelogs/8.16.asciidoc[] include::./changelogs/8.15.asciidoc[] include::./changelogs/8.14.asciidoc[] include::./changelogs/8.13.asciidoc[] diff --git a/Makefile b/Makefile index 30e5d691ff4..f69fce7e395 100644 --- a/Makefile +++ b/Makefile @@ -19,6 +19,9 @@ PYTHON_BIN:=$(PYTHON_VENV_DIR)/bin PYTHON=$(PYTHON_BIN)/python CURRENT_DIR=$(shell dirname $(shell readlink -f $(firstword $(MAKEFILE_LIST)))) +# Support DRA qualifier with the following environment variable. +ELASTIC_QUALIFIER?= + # Create a local config.mk file to override configuration. -include config.mk @@ -38,6 +41,7 @@ APM_SERVER_BINARIES:= \ # Strip binary and inject the Git commit hash and timestamp. LDFLAGS := \ -s \ + -X github.com/elastic/apm-server/internal/version.qualifier=$(ELASTIC_QUALIFIER) \ -X github.com/elastic/beats/v7/libbeat/version.commit=$(GITCOMMIT) \ -X github.com/elastic/beats/v7/libbeat/version.buildTime=$(GITCOMMITTIMESTAMP) @@ -139,6 +143,11 @@ endif get-version: @echo $(APM_SERVER_VERSION) +## get-version-only : Get the apm server version without the qualifier +.PHONY: get-version-only +get-version-only: + @echo $(APM_SERVER_ONLY_VERSION) + # update-go-version updates .go-version, documentation, and build files # to use the most recent patch version for the major.minor Go version # defined in go.mod. @@ -180,12 +189,12 @@ BEATS_VERSION?=main BEATS_MODULE:=github.com/elastic/beats/v7 .PHONY: update-beats -update-beats: update-beats-module update +update-beats: update-beats-module tidy notice @echo --- Use this commit message: Update to elastic/beats@$(shell go list -m -f {{.Version}} $(BEATS_MODULE) | cut -d- -f3) .PHONY: update-beats-module update-beats-module: - go get -d $(BEATS_MODULE)@$(BEATS_VERSION) && go mod tidy + go get $(BEATS_MODULE)@$(BEATS_VERSION) && go mod tidy ############################################################################## # Linting, style-checking, license header checks, etc. diff --git a/NOTICE.txt b/NOTICE.txt index 751511b93bf..30ab989e0ec 100644 --- a/NOTICE.txt +++ b/NOTICE.txt @@ -1,5 +1,5 @@ Elastic APM Server -Copyright 2014-2024 Elasticsearch BV +Copyright 2014-2025 Elasticsearch BV This product includes software developed by The Apache Software Foundation (http://www.apache.org/). @@ -9,6 +9,37 @@ Third party libraries used by the Elastic APM Server project: ================================================================================ +-------------------------------------------------------------------------------- +Dependency : github.com/KimMachineGun/automemlimit +Version: v0.7.0 +Licence type (autodetected): MIT +-------------------------------------------------------------------------------- + +Contents of probable licence file $GOMODCACHE/github.com/!kim!machine!gun/automemlimit@v0.7.0/LICENSE: + +MIT License + +Copyright (c) 2022 Geon Kim + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + -------------------------------------------------------------------------------- Dependency : github.com/cespare/xxhash/v2 Version: v2.3.0 @@ -42,189 +73,40 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- -Dependency : github.com/dgraph-io/badger/v2 -Version: v2.2007.4 -Licence type (autodetected): Apache-2.0 +Dependency : github.com/cockroachdb/pebble/v2 +Version: v2.0.2 +Licence type (autodetected): BSD-3-Clause -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/github.com/dgraph-io/badger/v2@v2.2007.4/LICENSE: - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. +Contents of probable licence file $GOMODCACHE/github.com/cockroachdb/pebble/v2@v2.0.2/LICENSE: - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. +Copyright (c) 2011 The LevelDB-Go Authors. All rights reserved. - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. - END OF TERMS AND CONDITIONS +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- @@ -260,11 +142,11 @@ SOFTWARE. -------------------------------------------------------------------------------- Dependency : github.com/elastic/apm-aggregation -Version: v1.1.0 +Version: v1.2.0 Licence type (autodetected): Elastic-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/github.com/elastic/apm-aggregation@v1.1.0/LICENSE.txt: +Contents of probable licence file $GOMODCACHE/github.com/elastic/apm-aggregation@v1.2.0/LICENSE.txt: Elastic License 2.0 @@ -362,11 +244,11 @@ these terms. -------------------------------------------------------------------------------- Dependency : github.com/elastic/apm-data -Version: v1.13.1 +Version: v1.16.0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/github.com/elastic/apm-data@v1.13.1/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/elastic/apm-data@v1.16.0/LICENSE: Apache License Version 2.0, January 2004 @@ -573,11 +455,11 @@ Contents of probable licence file $GOMODCACHE/github.com/elastic/apm-data@v1.13. -------------------------------------------------------------------------------- Dependency : github.com/elastic/beats/v7 -Version: v7.0.0-alpha2.0.20240823193033-af33fad4d50b +Version: v7.0.0-alpha2.0.20241231140711-7806f1a2cb26 Licence type (autodetected): Elastic -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/github.com/elastic/beats/v7@v7.0.0-alpha2.0.20240823193033-af33fad4d50b/LICENSE.txt: +Contents of probable licence file $GOMODCACHE/github.com/elastic/beats/v7@v7.0.0-alpha2.0.20241231140711-7806f1a2cb26/LICENSE.txt: Source code in this repository is variously licensed under the Apache License Version 2.0, an Apache compatible license, or the Elastic License. Outside of @@ -596,11 +478,11 @@ License Version 2.0. -------------------------------------------------------------------------------- Dependency : github.com/elastic/elastic-agent-client/v7 -Version: v7.16.0 +Version: v7.17.0 Licence type (autodetected): Elastic -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/github.com/elastic/elastic-agent-client/v7@v7.16.0/LICENSE.txt: +Contents of probable licence file $GOMODCACHE/github.com/elastic/elastic-agent-client/v7@v7.17.0/LICENSE.txt: ELASTIC LICENSE AGREEMENT @@ -829,11 +711,11 @@ SOFTWARE -------------------------------------------------------------------------------- Dependency : github.com/elastic/elastic-agent-libs -Version: v0.12.1 +Version: v0.18.3 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/github.com/elastic/elastic-agent-libs@v0.12.1/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/elastic/elastic-agent-libs@v0.18.3/LICENSE: Apache License Version 2.0, January 2004 @@ -1040,11 +922,11 @@ Contents of probable licence file $GOMODCACHE/github.com/elastic/elastic-agent-l -------------------------------------------------------------------------------- Dependency : github.com/elastic/elastic-agent-system-metrics -Version: v0.11.3 +Version: v0.11.7 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/github.com/elastic/elastic-agent-system-metrics@v0.11.3/LICENSE.txt: +Contents of probable licence file $GOMODCACHE/github.com/elastic/elastic-agent-system-metrics@v0.11.7/LICENSE.txt: Apache License Version 2.0, January 2004 @@ -1462,11 +1344,11 @@ Contents of probable licence file $GOMODCACHE/github.com/elastic/gmux@v0.3.2/LIC -------------------------------------------------------------------------------- Dependency : github.com/elastic/go-docappender/v2 -Version: v2.3.0 +Version: v2.4.0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/github.com/elastic/go-docappender/v2@v2.3.0/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/elastic/go-docappender/v2@v2.4.0/LICENSE: Apache License Version 2.0, January 2004 @@ -1673,11 +1555,11 @@ Contents of probable licence file $GOMODCACHE/github.com/elastic/go-docappender/ -------------------------------------------------------------------------------- Dependency : github.com/elastic/go-elasticsearch/v8 -Version: v8.15.0 +Version: v8.17.0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/github.com/elastic/go-elasticsearch/v8@v8.15.0/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/elastic/go-elasticsearch/v8@v8.17.0/LICENSE: Apache License Version 2.0, January 2004 @@ -1884,11 +1766,11 @@ Contents of probable licence file $GOMODCACHE/github.com/elastic/go-elasticsearc -------------------------------------------------------------------------------- Dependency : github.com/elastic/go-sysinfo -Version: v1.14.2 +Version: v1.15.0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/github.com/elastic/go-sysinfo@v1.14.2/LICENSE.txt: +Contents of probable licence file $GOMODCACHE/github.com/elastic/go-sysinfo@v1.15.0/LICENSE.txt: Apache License @@ -2379,12 +2261,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- -Dependency : github.com/gofrs/uuid -Version: v4.4.0+incompatible +Dependency : github.com/gofrs/uuid/v5 +Version: v5.3.0 Licence type (autodetected): MIT -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/github.com/gofrs/uuid@v4.4.0+incompatible/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/gofrs/uuid/v5@v5.3.0/LICENSE: Copyright (C) 2013-2018 by Maxim Bublis @@ -2865,23 +2747,76 @@ Exhibit B - "Incompatible With Secondary Licenses" Notice -------------------------------------------------------------------------------- -Dependency : github.com/jaegertracing/jaeger -Version: v1.60.0 -Licence type (autodetected): Apache-2.0 +Dependency : github.com/joeshaw/multierror +Version: v0.0.0-20140124173710-69b34d4ec901 +Licence type (autodetected): MIT -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/github.com/jaegertracing/jaeger@v1.60.0/LICENSE: - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ +Contents of probable licence file $GOMODCACHE/github.com/joeshaw/multierror@v0.0.0-20140124173710-69b34d4ec901/LICENSE: - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION +The MIT License (MIT) - 1. Definitions. +Copyright (c) 2014 Joe Shaw - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + +-------------------------------------------------------------------------------- +Dependency : github.com/libp2p/go-reuseport +Version: v0.4.0 +Licence type (autodetected): ISC +-------------------------------------------------------------------------------- + +Contents of probable licence file $GOMODCACHE/github.com/libp2p/go-reuseport@v0.4.0/LICENSE: + +Copyright (c) 2013 Conformal Systems LLC. + +Permission to use, copy, modify, and distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +-------------------------------------------------------------------------------- +Dependency : github.com/modern-go/reflect2 +Version: v1.0.2 +Licence type (autodetected): Apache-2.0 +-------------------------------------------------------------------------------- + +Contents of probable licence file $GOMODCACHE/github.com/modern-go/reflect2@v1.0.2/LICENSE: + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. @@ -3076,36 +3011,107 @@ Contents of probable licence file $GOMODCACHE/github.com/jaegertracing/jaeger@v1 -------------------------------------------------------------------------------- -Dependency : github.com/libp2p/go-reuseport -Version: v0.4.0 -Licence type (autodetected): ISC +Dependency : github.com/patrickmn/go-cache +Version: v2.1.0+incompatible +Licence type (autodetected): MIT -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/github.com/libp2p/go-reuseport@v0.4.0/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/patrickmn/go-cache@v2.1.0+incompatible/LICENSE: -Copyright (c) 2013 Conformal Systems LLC. +Copyright (c) 2012-2017 Patrick Mylund Nielsen and the go-cache contributors -Permission to use, copy, modify, and distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -------------------------------------------------------------------------------- -Dependency : github.com/modern-go/reflect2 -Version: v1.0.2 +Dependency : github.com/pkg/errors +Version: v0.9.1 +Licence type (autodetected): BSD-2-Clause +-------------------------------------------------------------------------------- + +Contents of probable licence file $GOMODCACHE/github.com/pkg/errors@v0.9.1/LICENSE: + +Copyright (c) 2015, Dave Cheney +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +-------------------------------------------------------------------------------- +Dependency : github.com/ryanuber/go-glob +Version: v1.0.0 +Licence type (autodetected): MIT +-------------------------------------------------------------------------------- + +Contents of probable licence file $GOMODCACHE/github.com/ryanuber/go-glob@v1.0.0/LICENSE: + +The MIT License (MIT) + +Copyright (c) 2014 Ryan Uber + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + +-------------------------------------------------------------------------------- +Dependency : github.com/spf13/cobra +Version: v1.8.1 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/github.com/modern-go/reflect2@v1.0.2/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/spf13/cobra@v1.8.1/LICENSE.txt: - Apache License + Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ @@ -3280,41 +3286,83 @@ Contents of probable licence file $GOMODCACHE/github.com/modern-go/reflect2@v1.0 incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. - END OF TERMS AND CONDITIONS - APPENDIX: How to apply the Apache License to your work. +-------------------------------------------------------------------------------- +Dependency : github.com/spf13/pflag +Version: v1.0.5 +Licence type (autodetected): BSD-3-Clause +-------------------------------------------------------------------------------- - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. +Contents of probable licence file $GOMODCACHE/github.com/spf13/pflag@v1.0.5/LICENSE: - Copyright [yyyy] [name of copyright owner] +Copyright (c) 2012 Alex Ogier. All rights reserved. +Copyright (c) 2012 The Go Authors. All rights reserved. - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: - http://www.apache.org/licenses/LICENSE-2.0 + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +-------------------------------------------------------------------------------- +Dependency : github.com/stretchr/testify +Version: v1.10.0 +Licence type (autodetected): MIT +-------------------------------------------------------------------------------- + +Contents of probable licence file $GOMODCACHE/github.com/stretchr/testify@v1.10.0/LICENSE: + +MIT License + +Copyright (c) 2012-2020 Mat Ryer, Tyler Bunnell and contributors. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. -------------------------------------------------------------------------------- -Dependency : github.com/open-telemetry/opentelemetry-collector-contrib/pkg/translator/jaeger -Version: v0.109.0 +Dependency : go.elastic.co/apm/module/apmelasticsearch/v2 +Version: v2.6.3 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/github.com/open-telemetry/opentelemetry-collector-contrib/pkg/translator/jaeger@v0.109.0/LICENSE: +Contents of probable licence file $GOMODCACHE/go.elastic.co/apm/module/apmelasticsearch/v2@v2.6.3/LICENSE: Apache License Version 2.0, January 2004 @@ -3504,7 +3552,7 @@ Contents of probable licence file $GOMODCACHE/github.com/open-telemetry/opentele same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright [yyyy] [name of copyright owner] + Copyright 2018 Elasticsearch BV Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -3520,109 +3568,16 @@ Contents of probable licence file $GOMODCACHE/github.com/open-telemetry/opentele -------------------------------------------------------------------------------- -Dependency : github.com/patrickmn/go-cache -Version: v2.1.0+incompatible -Licence type (autodetected): MIT +Dependency : go.elastic.co/apm/module/apmgorilla/v2 +Version: v2.6.3 +Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/github.com/patrickmn/go-cache@v2.1.0+incompatible/LICENSE: +Contents of probable licence file $GOMODCACHE/go.elastic.co/apm/module/apmgorilla/v2@v2.6.3/LICENSE: -Copyright (c) 2012-2017 Patrick Mylund Nielsen and the go-cache contributors - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - - --------------------------------------------------------------------------------- -Dependency : github.com/pkg/errors -Version: v0.9.1 -Licence type (autodetected): BSD-2-Clause --------------------------------------------------------------------------------- - -Contents of probable licence file $GOMODCACHE/github.com/pkg/errors@v0.9.1/LICENSE: - -Copyright (c) 2015, Dave Cheney -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - --------------------------------------------------------------------------------- -Dependency : github.com/ryanuber/go-glob -Version: v1.0.0 -Licence type (autodetected): MIT --------------------------------------------------------------------------------- - -Contents of probable licence file $GOMODCACHE/github.com/ryanuber/go-glob@v1.0.0/LICENSE: - -The MIT License (MIT) - -Copyright (c) 2014 Ryan Uber - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - - --------------------------------------------------------------------------------- -Dependency : github.com/spf13/cobra -Version: v1.8.1 -Licence type (autodetected): Apache-2.0 --------------------------------------------------------------------------------- - -Contents of probable licence file $GOMODCACHE/github.com/spf13/cobra@v1.8.1/LICENSE.txt: - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION @@ -3795,52 +3750,41 @@ Contents of probable licence file $GOMODCACHE/github.com/spf13/cobra@v1.8.1/LICE incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. + END OF TERMS AND CONDITIONS --------------------------------------------------------------------------------- -Dependency : github.com/spf13/pflag -Version: v1.0.5 -Licence type (autodetected): BSD-3-Clause --------------------------------------------------------------------------------- + APPENDIX: How to apply the Apache License to your work. -Contents of probable licence file $GOMODCACHE/github.com/spf13/pflag@v1.0.5/LICENSE: + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. -Copyright (c) 2012 Alex Ogier. All rights reserved. -Copyright (c) 2012 The Go Authors. All rights reserved. + Copyright 2018 Elasticsearch BV -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. + http://www.apache.org/licenses/LICENSE-2.0 -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. -------------------------------------------------------------------------------- -Dependency : go.elastic.co/apm/module/apmelasticsearch/v2 -Version: v2.6.2 +Dependency : go.elastic.co/apm/module/apmgrpc/v2 +Version: v2.6.3 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/go.elastic.co/apm/module/apmelasticsearch/v2@v2.6.2/LICENSE: +Contents of probable licence file $GOMODCACHE/go.elastic.co/apm/module/apmgrpc/v2@v2.6.3/LICENSE: Apache License Version 2.0, January 2004 @@ -4046,12 +3990,12 @@ Contents of probable licence file $GOMODCACHE/go.elastic.co/apm/module/apmelasti -------------------------------------------------------------------------------- -Dependency : go.elastic.co/apm/module/apmgorilla/v2 -Version: v2.6.2 +Dependency : go.elastic.co/apm/module/apmhttp/v2 +Version: v2.6.3 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/go.elastic.co/apm/module/apmgorilla/v2@v2.6.2/LICENSE: +Contents of probable licence file $GOMODCACHE/go.elastic.co/apm/module/apmhttp/v2@v2.6.3/LICENSE: Apache License Version 2.0, January 2004 @@ -4257,12 +4201,12 @@ Contents of probable licence file $GOMODCACHE/go.elastic.co/apm/module/apmgorill -------------------------------------------------------------------------------- -Dependency : go.elastic.co/apm/module/apmgrpc/v2 -Version: v2.6.2 +Dependency : go.elastic.co/apm/module/apmotel/v2 +Version: v2.6.3 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/go.elastic.co/apm/module/apmgrpc/v2@v2.6.2/LICENSE: +Contents of probable licence file $GOMODCACHE/go.elastic.co/apm/module/apmotel/v2@v2.6.3/LICENSE: Apache License Version 2.0, January 2004 @@ -4468,12 +4412,12 @@ Contents of probable licence file $GOMODCACHE/go.elastic.co/apm/module/apmgrpc/v -------------------------------------------------------------------------------- -Dependency : go.elastic.co/apm/module/apmhttp/v2 -Version: v2.6.2 +Dependency : go.elastic.co/apm/v2 +Version: v2.6.3 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/go.elastic.co/apm/module/apmhttp/v2@v2.6.2/LICENSE: +Contents of probable licence file $GOMODCACHE/go.elastic.co/apm/v2@v2.6.3/LICENSE: Apache License Version 2.0, January 2004 @@ -4679,12 +4623,46 @@ Contents of probable licence file $GOMODCACHE/go.elastic.co/apm/module/apmhttp/v -------------------------------------------------------------------------------- -Dependency : go.elastic.co/apm/module/apmotel/v2 -Version: v2.6.2 +Dependency : go.elastic.co/fastjson +Version: v1.4.0 +Licence type (autodetected): MIT +-------------------------------------------------------------------------------- + +Contents of probable licence file $GOMODCACHE/go.elastic.co/fastjson@v1.4.0/LICENSE: + +Copyright 2018 Elasticsearch BV + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +--- + +Copyright (c) 2016 Mail.Ru Group + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +-------------------------------------------------------------------------------- +Dependency : go.opentelemetry.io/collector/pdata +Version: v1.24.0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/go.elastic.co/apm/module/apmotel/v2@v2.6.2/LICENSE: +Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/collector/pdata@v1.24.0/LICENSE: + Apache License Version 2.0, January 2004 @@ -4874,7 +4852,7 @@ Contents of probable licence file $GOMODCACHE/go.elastic.co/apm/module/apmotel/v same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright 2018 Elasticsearch BV + Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -4890,12 +4868,12 @@ Contents of probable licence file $GOMODCACHE/go.elastic.co/apm/module/apmotel/v -------------------------------------------------------------------------------- -Dependency : go.elastic.co/apm/v2 -Version: v2.6.2 +Dependency : go.opentelemetry.io/otel +Version: v1.34.0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/go.elastic.co/apm/v2@v2.6.2/LICENSE: +Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/otel@v1.34.0/LICENSE: Apache License Version 2.0, January 2004 @@ -5085,7 +5063,7 @@ Contents of probable licence file $GOMODCACHE/go.elastic.co/apm/v2@v2.6.2/LICENS same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright 2018 Elasticsearch BV + Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -5101,46 +5079,12 @@ Contents of probable licence file $GOMODCACHE/go.elastic.co/apm/v2@v2.6.2/LICENS -------------------------------------------------------------------------------- -Dependency : go.elastic.co/fastjson -Version: v1.4.0 -Licence type (autodetected): MIT --------------------------------------------------------------------------------- - -Contents of probable licence file $GOMODCACHE/go.elastic.co/fastjson@v1.4.0/LICENSE: - -Copyright 2018 Elasticsearch BV - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - ---- - -Copyright (c) 2016 Mail.Ru Group - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - --------------------------------------------------------------------------------- -Dependency : go.opentelemetry.io/collector/consumer -Version: v0.109.0 +Dependency : go.opentelemetry.io/otel/metric +Version: v1.34.0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/collector/consumer@v0.109.0/LICENSE: - +Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/otel/metric@v1.34.0/LICENSE: Apache License Version 2.0, January 2004 @@ -5346,13 +5290,12 @@ Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/collector/cons -------------------------------------------------------------------------------- -Dependency : go.opentelemetry.io/collector/pdata -Version: v1.15.0 +Dependency : go.opentelemetry.io/otel/sdk/metric +Version: v1.34.0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/collector/pdata@v1.15.0/LICENSE: - +Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/otel/sdk/metric@v1.34.0/LICENSE: Apache License Version 2.0, January 2004 @@ -5558,23 +5501,258 @@ Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/collector/pdat -------------------------------------------------------------------------------- -Dependency : go.opentelemetry.io/otel -Version: v1.30.0 -Licence type (autodetected): Apache-2.0 +Dependency : go.uber.org/automaxprocs +Version: v1.6.0 +Licence type (autodetected): MIT -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/otel@v1.30.0/LICENSE: - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ +Contents of probable licence file $GOMODCACHE/go.uber.org/automaxprocs@v1.6.0/LICENSE: - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION +Copyright (c) 2017 Uber Technologies, Inc. - 1. Definitions. +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +-------------------------------------------------------------------------------- +Dependency : go.uber.org/zap +Version: v1.27.0 +Licence type (autodetected): MIT +-------------------------------------------------------------------------------- + +Contents of probable licence file $GOMODCACHE/go.uber.org/zap@v1.27.0/LICENSE: + +Copyright (c) 2016-2017 Uber Technologies, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + +-------------------------------------------------------------------------------- +Dependency : go.uber.org/zap/exp +Version: v0.3.0 +Licence type (autodetected): MIT +-------------------------------------------------------------------------------- + +Contents of probable licence file $GOMODCACHE/go.uber.org/zap/exp@v0.3.0/LICENSE: + +Copyright (c) 2016-2024 Uber Technologies, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + +-------------------------------------------------------------------------------- +Dependency : golang.org/x/net +Version: v0.34.0 +Licence type (autodetected): BSD-3-Clause +-------------------------------------------------------------------------------- + +Contents of probable licence file $GOMODCACHE/golang.org/x/net@v0.34.0/LICENSE: + +Copyright 2009 The Go Authors. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google LLC nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +-------------------------------------------------------------------------------- +Dependency : golang.org/x/sync +Version: v0.10.0 +Licence type (autodetected): BSD-3-Clause +-------------------------------------------------------------------------------- + +Contents of probable licence file $GOMODCACHE/golang.org/x/sync@v0.10.0/LICENSE: + +Copyright 2009 The Go Authors. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google LLC nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +-------------------------------------------------------------------------------- +Dependency : golang.org/x/term +Version: v0.28.0 +Licence type (autodetected): BSD-3-Clause +-------------------------------------------------------------------------------- + +Contents of probable licence file $GOMODCACHE/golang.org/x/term@v0.28.0/LICENSE: + +Copyright 2009 The Go Authors. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google LLC nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +-------------------------------------------------------------------------------- +Dependency : golang.org/x/time +Version: v0.9.0 +Licence type (autodetected): BSD-3-Clause +-------------------------------------------------------------------------------- + +Contents of probable licence file $GOMODCACHE/golang.org/x/time@v0.9.0/LICENSE: + +Copyright 2009 The Go Authors. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google LLC nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +-------------------------------------------------------------------------------- +Dependency : google.golang.org/grpc +Version: v1.70.0 +Licence type (autodetected): Apache-2.0 +-------------------------------------------------------------------------------- + +Contents of probable licence file $GOMODCACHE/google.golang.org/grpc@v1.70.0/LICENSE: + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. @@ -5769,237 +5947,286 @@ Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/otel@v1.30.0/L -------------------------------------------------------------------------------- -Dependency : go.opentelemetry.io/otel/metric -Version: v1.30.0 -Licence type (autodetected): Apache-2.0 +Dependency : google.golang.org/protobuf +Version: v1.36.4 +Licence type (autodetected): BSD-3-Clause -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/otel/metric@v1.30.0/LICENSE: - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION +Contents of probable licence file $GOMODCACHE/google.golang.org/protobuf@v1.36.4/LICENSE: - 1. Definitions. +Copyright (c) 2018 The Go Authors. All rights reserved. - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. +-------------------------------------------------------------------------------- +Dependency : gopkg.in/yaml.v3 +Version: v3.0.1 +Licence type (autodetected): MIT +-------------------------------------------------------------------------------- - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. +Contents of probable licence file $GOMODCACHE/gopkg.in/yaml.v3@v3.0.1/LICENSE: - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. +This project is covered by two different licenses: MIT and Apache. - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." +#### MIT License #### - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. +The following files were ported to Go from C files of libyaml, and thus +are still covered by their original MIT license, with the additional +copyright staring in 2011 when the project was ported over: - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. + apic.go emitterc.go parserc.go readerc.go scannerc.go + writerc.go yamlh.go yamlprivateh.go - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. +Copyright (c) 2006-2010 Kirill Simonov +Copyright (c) 2006-2011 Kirill Simonov - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and +### Apache License ### - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. +All the remaining project files are covered by the Apache license: - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. +Copyright (c) 2011-2019 Canonical Ltd - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. + http://www.apache.org/licenses/LICENSE-2.0 - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - END OF TERMS AND CONDITIONS - APPENDIX: How to apply the Apache License to your work. +================================================================================ +Indirect dependencies - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - Copyright [yyyy] [name of copyright owner] +-------------------------------------------------------------------------------- +Dependency : github.com/DataDog/zstd +Version: v1.5.6 +Licence type (autodetected): BSD-3-Clause +-------------------------------------------------------------------------------- - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at +Contents of probable licence file $GOMODCACHE/github.com/!data!dog/zstd@v1.5.6/LICENSE: - http://www.apache.org/licenses/LICENSE-2.0 +Simplified BSD License - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. +Copyright (c) 2016, Datadog +All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: --------------------------------------------------------------------------------- -Dependency : go.opentelemetry.io/otel/sdk/metric -Version: v1.30.0 -Licence type (autodetected): Apache-2.0 --------------------------------------------------------------------------------- + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. -Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/otel/sdk/metric@v1.30.0/LICENSE: +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION +-------------------------------------------------------------------------------- +Dependency : github.com/Microsoft/go-winio +Version: v0.6.2 +Licence type (autodetected): MIT +-------------------------------------------------------------------------------- - 1. Definitions. +Contents of probable licence file $GOMODCACHE/github.com/!microsoft/go-winio@v0.6.2/LICENSE: - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. +The MIT License (MIT) - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. +Copyright (c) 2015 Microsoft + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + + +-------------------------------------------------------------------------------- +Dependency : github.com/armon/go-radix +Version: v1.0.0 +Licence type (autodetected): MIT +-------------------------------------------------------------------------------- + +Contents of probable licence file $GOMODCACHE/github.com/armon/go-radix@v1.0.0/LICENSE: + +The MIT License (MIT) + +Copyright (c) 2014 Armon Dadgar + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +-------------------------------------------------------------------------------- +Dependency : github.com/axiomhq/hyperloglog +Version: v0.2.0 +Licence type (autodetected): MIT +-------------------------------------------------------------------------------- + +Contents of probable licence file $GOMODCACHE/github.com/axiomhq/hyperloglog@v0.2.0/LICENSE: + +Copyright (c) 2021, Axiom, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +-------------------------------------------------------------------------------- +Dependency : github.com/beorn7/perks +Version: v1.0.1 +Licence type (autodetected): MIT +-------------------------------------------------------------------------------- + +Contents of probable licence file $GOMODCACHE/github.com/beorn7/perks@v1.0.1/LICENSE: + +Copyright (C) 2013 Blake Mizerany + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +-------------------------------------------------------------------------------- +Dependency : github.com/cockroachdb/crlib +Version: v0.0.0-20241015224233-894974b3ad94 +Licence type (autodetected): Apache-2.0 +-------------------------------------------------------------------------------- + +Contents of probable licence file $GOMODCACHE/github.com/cockroachdb/crlib@v0.0.0-20241015224233-894974b3ad94/LICENSE: + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common @@ -6191,218 +6418,223 @@ Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/otel/sdk/metri -------------------------------------------------------------------------------- -Dependency : go.uber.org/automaxprocs -Version: v1.6.0 -Licence type (autodetected): MIT +Dependency : github.com/cockroachdb/errors +Version: v1.11.3 +Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/go.uber.org/automaxprocs@v1.6.0/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/cockroachdb/errors@v1.11.3/LICENSE: -Copyright (c) 2017 Uber Technologies, Inc. + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. + 1. Definitions. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. --------------------------------------------------------------------------------- -Dependency : go.uber.org/zap -Version: v1.27.0 -Licence type (autodetected): MIT --------------------------------------------------------------------------------- + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. -Contents of probable licence file $GOMODCACHE/go.uber.org/zap@v1.27.0/LICENSE: + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. -Copyright (c) 2016-2017 Uber Technologies, Inc. + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. --------------------------------------------------------------------------------- -Dependency : golang.org/x/net -Version: v0.30.0 -Licence type (autodetected): BSD-3-Clause --------------------------------------------------------------------------------- + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." -Contents of probable licence file $GOMODCACHE/golang.org/x/net@v0.30.0/LICENSE: + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. -Copyright 2009 The Go Authors. + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google LLC nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - --------------------------------------------------------------------------------- -Dependency : golang.org/x/sync -Version: v0.8.0 -Licence type (autodetected): BSD-3-Clause --------------------------------------------------------------------------------- - -Contents of probable licence file $GOMODCACHE/golang.org/x/sync@v0.8.0/LICENSE: - -Copyright 2009 The Go Authors. + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google LLC nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. --------------------------------------------------------------------------------- -Dependency : golang.org/x/term -Version: v0.25.0 -Licence type (autodetected): BSD-3-Clause --------------------------------------------------------------------------------- + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. -Contents of probable licence file $GOMODCACHE/golang.org/x/term@v0.25.0/LICENSE: + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. -Copyright 2009 The Go Authors. + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google LLC nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + END OF TERMS AND CONDITIONS --------------------------------------------------------------------------------- -Dependency : golang.org/x/time -Version: v0.7.0 -Licence type (autodetected): BSD-3-Clause --------------------------------------------------------------------------------- + APPENDIX: How to apply the Apache License to your work. -Contents of probable licence file $GOMODCACHE/golang.org/x/time@v0.7.0/LICENSE: + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. -Copyright 2009 The Go Authors. + Copyright [yyyy] [name of copyright owner] -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google LLC nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. + http://www.apache.org/licenses/LICENSE-2.0 -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. -------------------------------------------------------------------------------- -Dependency : google.golang.org/grpc -Version: v1.67.1 +Dependency : github.com/cockroachdb/fifo +Version: v0.0.0-20240816210425-c5d0cb0b6fc0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/google.golang.org/grpc@v1.67.1/LICENSE: - +Contents of probable licence file $GOMODCACHE/github.com/cockroachdb/fifo@v0.0.0-20240816210425-c5d0cb0b6fc0/LICENSE: Apache License Version 2.0, January 2004 @@ -6608,229 +6840,26 @@ Contents of probable licence file $GOMODCACHE/google.golang.org/grpc@v1.67.1/LIC -------------------------------------------------------------------------------- -Dependency : google.golang.org/protobuf -Version: v1.35.1 -Licence type (autodetected): BSD-3-Clause +Dependency : github.com/cockroachdb/logtags +Version: v0.0.0-20230118201751-21c54148d20b +Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/google.golang.org/protobuf@v1.35.1/LICENSE: - -Copyright (c) 2018 The Go Authors. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: +Contents of probable licence file $GOMODCACHE/github.com/cockroachdb/logtags@v0.0.0-20230118201751-21c54148d20b/LICENSE: - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + 1. Definitions. --------------------------------------------------------------------------------- -Dependency : gopkg.in/yaml.v3 -Version: v3.0.1 -Licence type (autodetected): MIT --------------------------------------------------------------------------------- + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. -Contents of probable licence file $GOMODCACHE/gopkg.in/yaml.v3@v3.0.1/LICENSE: - - -This project is covered by two different licenses: MIT and Apache. - -#### MIT License #### - -The following files were ported to Go from C files of libyaml, and thus -are still covered by their original MIT license, with the additional -copyright staring in 2011 when the project was ported over: - - apic.go emitterc.go parserc.go readerc.go scannerc.go - writerc.go yamlh.go yamlprivateh.go - -Copyright (c) 2006-2010 Kirill Simonov -Copyright (c) 2006-2011 Kirill Simonov - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is furnished to do -so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - -### Apache License ### - -All the remaining project files are covered by the Apache license: - -Copyright (c) 2011-2019 Canonical Ltd - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - - - - -================================================================================ -Indirect dependencies - - --------------------------------------------------------------------------------- -Dependency : github.com/DataDog/zstd -Version: v1.4.5 -Licence type (autodetected): BSD-3-Clause --------------------------------------------------------------------------------- - -Contents of probable licence file $GOMODCACHE/github.com/!data!dog/zstd@v1.4.5/LICENSE: - -Simplified BSD License - -Copyright (c) 2016, Datadog -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - * Neither the name of the copyright holder nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - --------------------------------------------------------------------------------- -Dependency : github.com/Microsoft/go-winio -Version: v0.6.2 -Licence type (autodetected): MIT --------------------------------------------------------------------------------- - -Contents of probable licence file $GOMODCACHE/github.com/!microsoft/go-winio@v0.6.2/LICENSE: - -The MIT License (MIT) - -Copyright (c) 2015 Microsoft - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - - - --------------------------------------------------------------------------------- -Dependency : github.com/elastic/sarama -Version: v1.19.1-0.20210823122811-11c3ef800752 -Licence type (autodetected): MIT --------------------------------------------------------------------------------- - -Contents of probable licence file $GOMODCACHE/github.com/elastic/sarama@v1.19.1-0.20210823122811-11c3ef800752/LICENSE: - -Copyright (c) 2013 Shopify - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - --------------------------------------------------------------------------------- -Dependency : github.com/apache/thrift -Version: v0.20.0 -Licence type (autodetected): Apache-2.0 --------------------------------------------------------------------------------- - -Contents of probable licence file $GOMODCACHE/github.com/apache/thrift@v0.20.0/LICENSE: - - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common @@ -7020,249 +7049,62 @@ Contents of probable licence file $GOMODCACHE/github.com/apache/thrift@v0.20.0/L See the License for the specific language governing permissions and limitations under the License. --------------------------------------------------- -SOFTWARE DISTRIBUTED WITH THRIFT: - -The Apache Thrift software includes a number of subcomponents with -separate copyright notices and license terms. Your use of the source -code for the these subcomponents is subject to the terms and -conditions of the following licenses. - --------------------------------------------------- -Portions of the following files are licensed under the MIT License: - - lib/erl/src/Makefile.am - -Please see doc/otp-base-license.txt for the full terms of this license. - --------------------------------------------------- -For the aclocal/ax_boost_base.m4 and contrib/fb303/aclocal/ax_boost_base.m4 components: - -# Copyright (c) 2007 Thomas Porschberg -# -# Copying and distribution of this file, with or without -# modification, are permitted in any medium without royalty provided -# the copyright notice and this notice are preserved. - --------------------------------------------------- -For the lib/nodejs/lib/thrift/json_parse.js: - -/* - json_parse.js - 2015-05-02 - Public Domain. - NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. - -*/ -(By Douglas Crockford ) - --------------------------------------------------- -For lib/cpp/src/thrift/windows/SocketPair.cpp - -/* socketpair.c - * Copyright 2007 by Nathan C. Myers ; some rights reserved. - * This code is Free Software. It may be copied freely, in original or - * modified form, subject only to the restrictions that (1) the author is - * relieved from all responsibilities for any use for any purpose, and (2) - * this copyright notice must be retained, unchanged, in its entirety. If - * for any reason the author might be held responsible for any consequences - * of copying or use, license is withheld. - */ - - --------------------------------------------------- -For lib/py/compat/win32/stdint.h - -// ISO C9x compliant stdint.h for Microsoft Visual Studio -// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 -// -// Copyright (c) 2006-2008 Alexander Chemeris -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// 3. The name of the author may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED -// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO -// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; -// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR -// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -/////////////////////////////////////////////////////////////////////////////// - - --------------------------------------------------- -Codegen template in t_html_generator.h - -* Bootstrap v2.0.3 -* -* Copyright 2012 Twitter, Inc -* Licensed under the Apache License v2.0 -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Designed and built with all the love in the world @twitter by @mdo and @fat. - ---------------------------------------------------- -For t_cl_generator.cc - - * Copyright (c) 2008- Patrick Collison - * Copyright (c) 2006- Facebook - ---------------------------------------------------- - -------------------------------------------------------------------------------- -Dependency : github.com/armon/go-radix -Version: v1.0.0 -Licence type (autodetected): MIT +Dependency : github.com/cockroachdb/pebble +Version: v1.1.2 +Licence type (autodetected): BSD-3-Clause -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/github.com/armon/go-radix@v1.0.0/LICENSE: - -The MIT License (MIT) +Contents of probable licence file $GOMODCACHE/github.com/cockroachdb/pebble@v1.1.2/LICENSE: -Copyright (c) 2014 Armon Dadgar +Copyright (c) 2011 The LevelDB-Go Authors. All rights reserved. -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- -Dependency : github.com/axiomhq/hyperloglog -Version: v0.2.0 -Licence type (autodetected): MIT +Dependency : github.com/cockroachdb/redact +Version: v1.1.5 +Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/github.com/axiomhq/hyperloglog@v0.2.0/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/cockroachdb/redact@v1.1.5/LICENSE: -Copyright (c) 2021, Axiom, Inc. + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. + 1. Definitions. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - --------------------------------------------------------------------------------- -Dependency : github.com/beorn7/perks -Version: v1.0.1 -Licence type (autodetected): MIT --------------------------------------------------------------------------------- - -Contents of probable licence file $GOMODCACHE/github.com/beorn7/perks@v1.0.1/LICENSE: - -Copyright (C) 2013 Blake Mizerany - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - --------------------------------------------------------------------------------- -Dependency : github.com/cespare/xxhash -Version: v1.1.0 -Licence type (autodetected): MIT --------------------------------------------------------------------------------- - -Contents of probable licence file $GOMODCACHE/github.com/cespare/xxhash@v1.1.0/LICENSE.txt: - -Copyright (c) 2016 Caleb Spare - -MIT License - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - --------------------------------------------------------------------------------- -Dependency : github.com/cockroachdb/errors -Version: v1.11.3 -Licence type (autodetected): Apache-2.0 --------------------------------------------------------------------------------- - -Contents of probable licence file $GOMODCACHE/github.com/cockroachdb/errors@v1.11.3/LICENSE: - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. @@ -7457,14 +7299,14 @@ Contents of probable licence file $GOMODCACHE/github.com/cockroachdb/errors@v1.1 -------------------------------------------------------------------------------- -Dependency : github.com/cockroachdb/fifo -Version: v0.0.0-20240606204812-0bbfbd93a7ce +Dependency : github.com/cockroachdb/swiss +Version: v0.0.0-20240612210725-f4de07ae6964 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/github.com/cockroachdb/fifo@v0.0.0-20240606204812-0bbfbd93a7ce/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/cockroachdb/swiss@v0.0.0-20240612210725-f4de07ae6964/LICENSE: - Apache License +Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ @@ -7644,7 +7486,7 @@ Contents of probable licence file $GOMODCACHE/github.com/cockroachdb/fifo@v0.0.0 APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" + boilerplate notice, with the fields enclosed by brackets "{}" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a @@ -7652,7 +7494,7 @@ Contents of probable licence file $GOMODCACHE/github.com/cockroachdb/fifo@v0.0.0 same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright [yyyy] [name of copyright owner] + Copyright {} Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -7667,13 +7509,14 @@ Contents of probable licence file $GOMODCACHE/github.com/cockroachdb/fifo@v0.0.0 limitations under the License. + -------------------------------------------------------------------------------- -Dependency : github.com/cockroachdb/logtags -Version: v0.0.0-20230118201751-21c54148d20b +Dependency : github.com/cockroachdb/tokenbucket +Version: v0.0.0-20230807174530-cc333fc44b06 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/github.com/cockroachdb/logtags@v0.0.0-20230118201751-21c54148d20b/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/cockroachdb/tokenbucket@v0.0.0-20230807174530-cc333fc44b06/LICENSE: Apache License Version 2.0, January 2004 @@ -7879,260 +7722,243 @@ Contents of probable licence file $GOMODCACHE/github.com/cockroachdb/logtags@v0. -------------------------------------------------------------------------------- -Dependency : github.com/cockroachdb/pebble -Version: v1.1.2 -Licence type (autodetected): BSD-3-Clause +Dependency : github.com/davecgh/go-spew +Version: v1.1.2-0.20180830191138-d8f796af33cc +Licence type (autodetected): ISC -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/github.com/cockroachdb/pebble@v1.1.2/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/davecgh/go-spew@v1.1.2-0.20180830191138-d8f796af33cc/LICENSE: -Copyright (c) 2011 The LevelDB-Go Authors. All rights reserved. +ISC License -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: +Copyright (c) 2012-2016 Dave Collins - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -------------------------------------------------------------------------------- -Dependency : github.com/cockroachdb/redact -Version: v1.1.5 -Licence type (autodetected): Apache-2.0 +Dependency : github.com/dgryski/go-metro +Version: v0.0.0-20211217172704-adc40b04c140 +Licence type (autodetected): MIT -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/github.com/cockroachdb/redact@v1.1.5/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/dgryski/go-metro@v0.0.0-20211217172704-adc40b04c140/LICENSE: - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ +This package is a mechanical translation of the reference C++ code for +MetroHash, available at https://github.com/jandrewrogers/MetroHash - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION +The MIT License (MIT) - 1. Definitions. +Copyright (c) 2016 Damian Gryski - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. +-------------------------------------------------------------------------------- +Dependency : github.com/dlclark/regexp2 +Version: v1.8.1 +Licence type (autodetected): MIT +-------------------------------------------------------------------------------- - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. +Contents of probable licence file $GOMODCACHE/github.com/dlclark/regexp2@v1.8.1/LICENSE: - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). +The MIT License (MIT) - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. +Copyright (c) Doug Clark - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: +-------------------------------------------------------------------------------- +Dependency : github.com/elastic/goja +Version: v0.0.0-20190128172624-dd2ac4456e20 +Licence type (autodetected): MIT +-------------------------------------------------------------------------------- - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and +Contents of probable licence file $GOMODCACHE/github.com/elastic/goja@v0.0.0-20190128172624-dd2ac4456e20/LICENSE: - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and +Copyright (c) 2016 Dmitry Panov - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and +Copyright (c) 2012 Robert Krimen - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to the following conditions: - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. +-------------------------------------------------------------------------------- +Dependency : github.com/dop251/goja_nodejs +Version: v0.0.0-20171011081505-adff31b136e6 +Licence type (autodetected): MIT +-------------------------------------------------------------------------------- - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. +Contents of probable licence file $GOMODCACHE/github.com/dop251/goja_nodejs@v0.0.0-20171011081505-adff31b136e6/LICENSE: - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. +Copyright (c) 2016 Dmitry Panov - END OF TERMS AND CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to the following conditions: - APPENDIX: How to apply the Apache License to your work. +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - Copyright [yyyy] [name of copyright owner] - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at +-------------------------------------------------------------------------------- +Dependency : github.com/eapache/go-resiliency +Version: v1.7.0 +Licence type (autodetected): MIT +-------------------------------------------------------------------------------- - http://www.apache.org/licenses/LICENSE-2.0 +Contents of probable licence file $GOMODCACHE/github.com/eapache/go-resiliency@v1.7.0/LICENSE: + +The MIT License (MIT) + +Copyright (c) 2014 Evan Huus + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -------------------------------------------------------------------------------- -Dependency : github.com/cockroachdb/tokenbucket -Version: v0.0.0-20230807174530-cc333fc44b06 +Dependency : github.com/eapache/go-xerial-snappy +Version: v0.0.0-20230731223053-c322873962e3 +Licence type (autodetected): MIT +-------------------------------------------------------------------------------- + +Contents of probable licence file $GOMODCACHE/github.com/eapache/go-xerial-snappy@v0.0.0-20230731223053-c322873962e3/LICENSE: + +The MIT License (MIT) + +Copyright (c) 2016 Evan Huus + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + +-------------------------------------------------------------------------------- +Dependency : github.com/eapache/queue +Version: v1.1.0 +Licence type (autodetected): MIT +-------------------------------------------------------------------------------- + +Contents of probable licence file $GOMODCACHE/github.com/eapache/queue@v1.1.0/LICENSE: + +The MIT License (MIT) + +Copyright (c) 2014 Evan Huus + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +-------------------------------------------------------------------------------- +Dependency : github.com/ebitengine/purego +Version: v0.8.0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/github.com/cockroachdb/tokenbucket@v0.0.0-20230807174530-cc333fc44b06/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/ebitengine/purego@v0.8.0/LICENSE: Apache License Version 2.0, January 2004 @@ -8314,7 +8140,7 @@ Contents of probable licence file $GOMODCACHE/github.com/cockroachdb/tokenbucket APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" + boilerplate notice, with the fields enclosed by brackets "{}" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a @@ -8322,7 +8148,7 @@ Contents of probable licence file $GOMODCACHE/github.com/cockroachdb/tokenbucket same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright [yyyy] [name of copyright owner] + Copyright {yyyy} {name of copyright owner} Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -8338,37 +8164,12 @@ Contents of probable licence file $GOMODCACHE/github.com/cockroachdb/tokenbucket -------------------------------------------------------------------------------- -Dependency : github.com/davecgh/go-spew -Version: v1.1.2-0.20180830191138-d8f796af33cc -Licence type (autodetected): ISC --------------------------------------------------------------------------------- - -Contents of probable licence file $GOMODCACHE/github.com/davecgh/go-spew@v1.1.2-0.20180830191138-d8f796af33cc/LICENSE: - -ISC License - -Copyright (c) 2012-2016 Dave Collins - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - --------------------------------------------------------------------------------- -Dependency : github.com/dgraph-io/ristretto -Version: v0.1.1 +Dependency : github.com/elastic/elastic-transport-go/v8 +Version: v8.6.0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/github.com/dgraph-io/ristretto@v0.1.1/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/elastic/elastic-transport-go/v8@v8.6.0/LICENSE: Apache License Version 2.0, January 2004 @@ -8547,251 +8348,40 @@ Contents of probable licence file $GOMODCACHE/github.com/dgraph-io/ristretto@v0. END OF TERMS AND CONDITIONS + APPENDIX: How to apply the Apache License to your work. --------------------------------------------------------------------------------- -Dependency : github.com/dgryski/go-farm -Version: v0.0.0-20200201041132-a6ae2369ad13 -Licence type (autodetected): MIT --------------------------------------------------------------------------------- - -Contents of probable licence file $GOMODCACHE/github.com/dgryski/go-farm@v0.0.0-20200201041132-a6ae2369ad13/LICENSE: - -Copyright (c) 2014-2017 Damian Gryski -Copyright (c) 2016-2017 Nicola Asuni - Tecnick.com - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - - - --------------------------------------------------------------------------------- -Dependency : github.com/dgryski/go-metro -Version: v0.0.0-20180109044635-280f6062b5bc -Licence type (autodetected): MIT --------------------------------------------------------------------------------- - -Contents of probable licence file $GOMODCACHE/github.com/dgryski/go-metro@v0.0.0-20180109044635-280f6062b5bc/LICENSE: - -This package is a mechanical translation of the reference C++ code for -MetroHash, available at https://github.com/jandrewrogers/MetroHash - -The MIT License (MIT) - -Copyright (c) 2016 Damian Gryski - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - - --------------------------------------------------------------------------------- -Dependency : github.com/dlclark/regexp2 -Version: v1.8.1 -Licence type (autodetected): MIT --------------------------------------------------------------------------------- - -Contents of probable licence file $GOMODCACHE/github.com/dlclark/regexp2@v1.8.1/LICENSE: - -The MIT License (MIT) - -Copyright (c) Doug Clark - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - - --------------------------------------------------------------------------------- -Dependency : github.com/andrewkroh/goja -Version: v0.0.0-20190128172624-dd2ac4456e20 -Licence type (autodetected): MIT --------------------------------------------------------------------------------- - -Contents of probable licence file $GOMODCACHE/github.com/andrewkroh/goja@v0.0.0-20190128172624-dd2ac4456e20/LICENSE: - -Copyright (c) 2016 Dmitry Panov - -Copyright (c) 2012 Robert Krimen - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the Software without restriction, including without limitation -the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE -WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - --------------------------------------------------------------------------------- -Dependency : github.com/dop251/goja_nodejs -Version: v0.0.0-20171011081505-adff31b136e6 -Licence type (autodetected): MIT --------------------------------------------------------------------------------- - -Contents of probable licence file $GOMODCACHE/github.com/dop251/goja_nodejs@v0.0.0-20171011081505-adff31b136e6/LICENSE: - -Copyright (c) 2016 Dmitry Panov - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the Software without restriction, including without limitation -the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE -WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - --------------------------------------------------------------------------------- -Dependency : github.com/eapache/go-resiliency -Version: v1.6.0 -Licence type (autodetected): MIT --------------------------------------------------------------------------------- - -Contents of probable licence file $GOMODCACHE/github.com/eapache/go-resiliency@v1.6.0/LICENSE: - -The MIT License (MIT) - -Copyright (c) 2014 Evan Huus - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - - - --------------------------------------------------------------------------------- -Dependency : github.com/eapache/go-xerial-snappy -Version: v0.0.0-20230731223053-c322873962e3 -Licence type (autodetected): MIT --------------------------------------------------------------------------------- - -Contents of probable licence file $GOMODCACHE/github.com/eapache/go-xerial-snappy@v0.0.0-20230731223053-c322873962e3/LICENSE: - -The MIT License (MIT) - -Copyright (c) 2016 Evan Huus - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - - --------------------------------------------------------------------------------- -Dependency : github.com/eapache/queue -Version: v1.1.0 -Licence type (autodetected): MIT --------------------------------------------------------------------------------- - -Contents of probable licence file $GOMODCACHE/github.com/eapache/queue@v1.1.0/LICENSE: + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. -The MIT License (MIT) + Copyright [yyyy] [name of copyright owner] -Copyright (c) 2014 Evan Huus + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: + http://www.apache.org/licenses/LICENSE-2.0 -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -------------------------------------------------------------------------------- -Dependency : github.com/elastic/elastic-transport-go/v8 -Version: v8.6.0 +Dependency : github.com/elastic/go-lumber +Version: v0.1.2-0.20220819171948-335fde24ea0f Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/github.com/elastic/elastic-transport-go/v8@v8.6.0/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/elastic/go-lumber@v0.1.2-0.20220819171948-335fde24ea0f/LICENSE: + Apache License Version 2.0, January 2004 @@ -8997,13 +8587,12 @@ Contents of probable licence file $GOMODCACHE/github.com/elastic/elastic-transpo -------------------------------------------------------------------------------- -Dependency : github.com/elastic/go-lumber -Version: v0.1.2-0.20220819171948-335fde24ea0f +Dependency : github.com/elastic/go-structform +Version: v0.0.10 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/github.com/elastic/go-lumber@v0.1.2-0.20220819171948-335fde24ea0f/LICENSE: - +Contents of probable licence file $GOMODCACHE/github.com/elastic/go-structform@v0.0.10/LICENSE: Apache License Version 2.0, January 2004 @@ -9185,7 +8774,7 @@ Contents of probable licence file $GOMODCACHE/github.com/elastic/go-lumber@v0.1. APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" + boilerplate notice, with the fields enclosed by brackets "{}" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a @@ -9193,7 +8782,7 @@ Contents of probable licence file $GOMODCACHE/github.com/elastic/go-lumber@v0.1. same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright [yyyy] [name of copyright owner] + Copyright 2012–2018 Elastic Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -9209,219 +8798,8 @@ Contents of probable licence file $GOMODCACHE/github.com/elastic/go-lumber@v0.1. -------------------------------------------------------------------------------- -Dependency : github.com/elastic/go-structform -Version: v0.0.10 -Licence type (autodetected): Apache-2.0 --------------------------------------------------------------------------------- - -Contents of probable licence file $GOMODCACHE/github.com/elastic/go-structform@v0.0.10/LICENSE: - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2012–2018 Elastic - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - --------------------------------------------------------------------------------- -Dependency : github.com/elastic/go-windows -Version: v1.0.2 +Dependency : github.com/elastic/go-windows +Version: v1.0.2 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- @@ -9844,11 +9222,11 @@ limitations under the License. -------------------------------------------------------------------------------- Dependency : github.com/elastic/opentelemetry-lib -Version: v0.9.0 +Version: v0.14.0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/github.com/elastic/opentelemetry-lib@v0.9.0/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/elastic/opentelemetry-lib@v0.14.0/LICENSE: Apache License Version 2.0, January 2004 @@ -10083,6 +9461,40 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +-------------------------------------------------------------------------------- +Dependency : github.com/elastic/sarama +Version: v1.19.1-0.20241120141909-c7eabfcee7e5 +Licence type (autodetected): MIT +-------------------------------------------------------------------------------- + +Contents of probable licence file $GOMODCACHE/github.com/elastic/sarama@v1.19.1-0.20241120141909-c7eabfcee7e5/LICENSE.md: + +# MIT License + +Copyright (c) 2013 Shopify + +Copyright (c) 2023 IBM Corporation + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + -------------------------------------------------------------------------------- Dependency : github.com/fatih/color Version: v1.16.0 @@ -10115,11 +9527,11 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- Dependency : github.com/getsentry/sentry-go -Version: v0.27.0 +Version: v0.29.1 Licence type (autodetected): MIT -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/github.com/getsentry/sentry-go@v0.27.0/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/getsentry/sentry-go@v0.29.1/LICENSE: MIT License @@ -10598,265 +10010,14 @@ SOFTWARE. -------------------------------------------------------------------------------- -Dependency : github.com/gofrs/uuid/v5 -Version: v5.2.0 -Licence type (autodetected): MIT +Dependency : github.com/golang/protobuf +Version: v1.5.4 +Licence type (autodetected): BSD-3-Clause -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/github.com/gofrs/uuid/v5@v5.2.0/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/golang/protobuf@v1.5.4/LICENSE: -Copyright (C) 2013-2018 by Maxim Bublis - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - --------------------------------------------------------------------------------- -Dependency : github.com/gogo/googleapis -Version: v1.4.1 -Licence type (autodetected): Apache-2.0 --------------------------------------------------------------------------------- - -Contents of probable licence file $GOMODCACHE/github.com/gogo/googleapis@v1.4.1/LICENSE: - -Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2015, Google Inc - Copyright 2018, GoGo Authors - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - - --------------------------------------------------------------------------------- -Dependency : github.com/golang/glog -Version: v1.2.2 -Licence type (autodetected): Apache-2.0 --------------------------------------------------------------------------------- - -No licence file provided. - --------------------------------------------------------------------------------- -Dependency : github.com/golang/protobuf -Version: v1.5.4 -Licence type (autodetected): BSD-3-Clause --------------------------------------------------------------------------------- - -Contents of probable licence file $GOMODCACHE/github.com/golang/protobuf@v1.5.4/LICENSE: - -Copyright 2010 The Go Authors. All rights reserved. +Copyright 2010 The Go Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are @@ -10888,11 +10049,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- Dependency : github.com/golang/snappy -Version: v0.0.4 +Version: v0.0.5-0.20231225225746-43d5d4cd4e0e Licence type (autodetected): BSD-3-Clause -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/github.com/golang/snappy@v0.0.4/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/golang/snappy@v0.0.5-0.20231225225746-43d5d4cd4e0e/LICENSE: Copyright (c) 2011 The Snappy-Go Authors. All rights reserved. @@ -11182,102 +10343,100 @@ OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- -Dependency : github.com/hashicorp/go-uuid -Version: v1.0.3 +Dependency : github.com/hashicorp/errwrap +Version: v1.1.0 Licence type (autodetected): MPL-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/github.com/hashicorp/go-uuid@v1.0.3/LICENSE: - -Copyright © 2015-2022 HashiCorp, Inc. +Contents of probable licence file $GOMODCACHE/github.com/hashicorp/errwrap@v1.1.0/LICENSE: Mozilla Public License, version 2.0 1. Definitions -1.1. "Contributor" +1.1. “Contributor” means each individual or legal entity that creates, contributes to the creation of, or owns Covered Software. -1.2. "Contributor Version" +1.2. “Contributor Version” means the combination of the Contributions of others (if any) used by a - Contributor and that particular Contributor's Contribution. + Contributor and that particular Contributor’s Contribution. -1.3. "Contribution" +1.3. “Contribution” means Covered Software of a particular Contributor. -1.4. "Covered Software" +1.4. “Covered Software” means Source Code Form to which the initial Contributor has attached the notice in Exhibit A, the Executable Form of such Source Code Form, and Modifications of such Source Code Form, in each case including portions thereof. -1.5. "Incompatible With Secondary Licenses" +1.5. “Incompatible With Secondary Licenses” means a. that the initial Contributor has attached the notice described in Exhibit B to the Covered Software; or - b. that the Covered Software was made available under the terms of - version 1.1 or earlier of the License, but not also under the terms of - a Secondary License. + b. that the Covered Software was made available under the terms of version + 1.1 or earlier of the License, but not also under the terms of a + Secondary License. -1.6. "Executable Form" +1.6. “Executable Form” means any form of the work other than Source Code Form. -1.7. "Larger Work" +1.7. “Larger Work” - means a work that combines Covered Software with other material, in a - separate file or files, that is not Covered Software. + means a work that combines Covered Software with other material, in a separate + file or files, that is not Covered Software. -1.8. "License" +1.8. “License” means this document. -1.9. "Licensable" +1.9. “Licensable” - means having the right to grant, to the maximum extent possible, whether - at the time of the initial grant or subsequently, any and all of the - rights conveyed by this License. + means having the right to grant, to the maximum extent possible, whether at the + time of the initial grant or subsequently, any and all of the rights conveyed by + this License. -1.10. "Modifications" +1.10. “Modifications” means any of the following: - a. any file in Source Code Form that results from an addition to, - deletion from, or modification of the contents of Covered Software; or + a. any file in Source Code Form that results from an addition to, deletion + from, or modification of the contents of Covered Software; or b. any new file in Source Code Form that contains any Covered Software. -1.11. "Patent Claims" of a Contributor +1.11. “Patent Claims” of a Contributor - means any patent claim(s), including without limitation, method, - process, and apparatus claims, in any patent Licensable by such - Contributor that would be infringed, but for the grant of the License, - by the making, using, selling, offering for sale, having made, import, - or transfer of either its Contributions or its Contributor Version. + means any patent claim(s), including without limitation, method, process, + and apparatus claims, in any patent Licensable by such Contributor that + would be infringed, but for the grant of the License, by the making, + using, selling, offering for sale, having made, import, or transfer of + either its Contributions or its Contributor Version. -1.12. "Secondary License" +1.12. “Secondary License” means either the GNU General Public License, Version 2.0, the GNU Lesser General Public License, Version 2.1, the GNU Affero General Public License, Version 3.0, or any later versions of those licenses. -1.13. "Source Code Form" +1.13. “Source Code Form” means the form of the work preferred for making modifications. -1.14. "You" (or "Your") +1.14. “You” (or “Your”) means an individual or a legal entity exercising rights under this - License. For legal entities, "You" includes any entity that controls, is + License. For legal entities, “You” includes any entity that controls, is controlled by, or is under common control with You. For purposes of this - definition, "control" means (a) the power, direct or indirect, to cause + definition, “control” means (a) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (b) ownership of more than fifty percent (50%) of the outstanding shares or beneficial ownership of such entity. @@ -11293,59 +10452,57 @@ Mozilla Public License, version 2.0 a. under intellectual property rights (other than patent or trademark) Licensable by such Contributor to use, reproduce, make available, modify, display, perform, distribute, and otherwise exploit its - Contributions, either on an unmodified basis, with Modifications, or - as part of a Larger Work; and + Contributions, either on an unmodified basis, with Modifications, or as + part of a Larger Work; and b. under Patent Claims of such Contributor to make, use, sell, offer for - sale, have made, import, and otherwise transfer either its - Contributions or its Contributor Version. + sale, have made, import, and otherwise transfer either its Contributions + or its Contributor Version. 2.2. Effective Date - The licenses granted in Section 2.1 with respect to any Contribution - become effective for each Contribution on the date the Contributor first - distributes such Contribution. + The licenses granted in Section 2.1 with respect to any Contribution become + effective for each Contribution on the date the Contributor first distributes + such Contribution. 2.3. Limitations on Grant Scope - The licenses granted in this Section 2 are the only rights granted under - this License. No additional rights or licenses will be implied from the - distribution or licensing of Covered Software under this License. - Notwithstanding Section 2.1(b) above, no patent license is granted by a - Contributor: + The licenses granted in this Section 2 are the only rights granted under this + License. No additional rights or licenses will be implied from the distribution + or licensing of Covered Software under this License. Notwithstanding Section + 2.1(b) above, no patent license is granted by a Contributor: a. for any code that a Contributor has removed from Covered Software; or - b. for infringements caused by: (i) Your and any other third party's + b. for infringements caused by: (i) Your and any other third party’s modifications of Covered Software, or (ii) the combination of its Contributions with other software (except as part of its Contributor Version); or - c. under Patent Claims infringed by Covered Software in the absence of - its Contributions. + c. under Patent Claims infringed by Covered Software in the absence of its + Contributions. - This License does not grant any rights in the trademarks, service marks, - or logos of any Contributor (except as may be necessary to comply with - the notice requirements in Section 3.4). + This License does not grant any rights in the trademarks, service marks, or + logos of any Contributor (except as may be necessary to comply with the + notice requirements in Section 3.4). 2.4. Subsequent Licenses No Contributor makes additional grants as a result of Your choice to - distribute the Covered Software under a subsequent version of this - License (see Section 10.2) or under the terms of a Secondary License (if - permitted under the terms of Section 3.3). + distribute the Covered Software under a subsequent version of this License + (see Section 10.2) or under the terms of a Secondary License (if permitted + under the terms of Section 3.3). 2.5. Representation - Each Contributor represents that the Contributor believes its - Contributions are its original creation(s) or it has sufficient rights to - grant the rights to its Contributions conveyed by this License. + Each Contributor represents that the Contributor believes its Contributions + are its original creation(s) or it has sufficient rights to grant the + rights to its Contributions conveyed by this License. 2.6. Fair Use - This License is not intended to limit any rights You have under - applicable copyright doctrines of fair use, fair dealing, or other - equivalents. + This License is not intended to limit any rights You have under applicable + copyright doctrines of fair use, fair dealing, or other equivalents. 2.7. Conditions @@ -11358,12 +10515,11 @@ Mozilla Public License, version 2.0 3.1. Distribution of Source Form All distribution of Covered Software in Source Code Form, including any - Modifications that You create or to which You contribute, must be under - the terms of this License. You must inform recipients that the Source - Code Form of the Covered Software is governed by the terms of this - License, and how they can obtain a copy of this License. You may not - attempt to alter or restrict the recipients' rights in the Source Code - Form. + Modifications that You create or to which You contribute, must be under the + terms of this License. You must inform recipients that the Source Code Form + of the Covered Software is governed by the terms of this License, and how + they can obtain a copy of this License. You may not attempt to alter or + restrict the recipients’ rights in the Source Code Form. 3.2. Distribution of Executable Form @@ -11375,40 +10531,39 @@ Mozilla Public License, version 2.0 reasonable means in a timely manner, at a charge no more than the cost of distribution to the recipient; and - b. You may distribute such Executable Form under the terms of this - License, or sublicense it under different terms, provided that the - license for the Executable Form does not attempt to limit or alter the - recipients' rights in the Source Code Form under this License. + b. You may distribute such Executable Form under the terms of this License, + or sublicense it under different terms, provided that the license for + the Executable Form does not attempt to limit or alter the recipients’ + rights in the Source Code Form under this License. 3.3. Distribution of a Larger Work You may create and distribute a Larger Work under terms of Your choice, - provided that You also comply with the requirements of this License for - the Covered Software. If the Larger Work is a combination of Covered - Software with a work governed by one or more Secondary Licenses, and the - Covered Software is not Incompatible With Secondary Licenses, this - License permits You to additionally distribute such Covered Software - under the terms of such Secondary License(s), so that the recipient of - the Larger Work may, at their option, further distribute the Covered - Software under the terms of either this License or such Secondary - License(s). + provided that You also comply with the requirements of this License for the + Covered Software. If the Larger Work is a combination of Covered Software + with a work governed by one or more Secondary Licenses, and the Covered + Software is not Incompatible With Secondary Licenses, this License permits + You to additionally distribute such Covered Software under the terms of + such Secondary License(s), so that the recipient of the Larger Work may, at + their option, further distribute the Covered Software under the terms of + either this License or such Secondary License(s). 3.4. Notices - You may not remove or alter the substance of any license notices - (including copyright notices, patent notices, disclaimers of warranty, or - limitations of liability) contained within the Source Code Form of the - Covered Software, except that You may alter any license notices to the - extent required to remedy known factual inaccuracies. + You may not remove or alter the substance of any license notices (including + copyright notices, patent notices, disclaimers of warranty, or limitations + of liability) contained within the Source Code Form of the Covered + Software, except that You may alter any license notices to the extent + required to remedy known factual inaccuracies. 3.5. Application of Additional Terms You may choose to offer, and to charge a fee for, warranty, support, indemnity or liability obligations to one or more recipients of Covered - Software. However, You may do so only on Your own behalf, and not on - behalf of any Contributor. You must make it absolutely clear that any - such warranty, support, indemnity, or liability obligation is offered by - You alone, and You hereby agree to indemnify every Contributor for any + Software. However, You may do so only on Your own behalf, and not on behalf + of any Contributor. You must make it absolutely clear that any such + warranty, support, indemnity, or liability obligation is offered by You + alone, and You hereby agree to indemnify every Contributor for any liability incurred by such Contributor as a result of warranty, support, indemnity or liability terms You offer. You may include additional disclaimers of warranty and limitations of liability specific to any @@ -11417,14 +10572,14 @@ Mozilla Public License, version 2.0 4. Inability to Comply Due to Statute or Regulation If it is impossible for You to comply with any of the terms of this License - with respect to some or all of the Covered Software due to statute, - judicial order, or regulation then You must: (a) comply with the terms of - this License to the maximum extent possible; and (b) describe the - limitations and the code they affect. Such description must be placed in a - text file included with all distributions of the Covered Software under - this License. Except to the extent prohibited by statute or regulation, - such description must be sufficiently detailed for a recipient of ordinary - skill to be able to understand it. + with respect to some or all of the Covered Software due to statute, judicial + order, or regulation then You must: (a) comply with the terms of this License + to the maximum extent possible; and (b) describe the limitations and the code + they affect. Such description must be placed in a text file included with all + distributions of the Covered Software under this License. Except to the + extent prohibited by statute or regulation, such description must be + sufficiently detailed for a recipient of ordinary skill to be able to + understand it. 5. Termination @@ -11432,22 +10587,21 @@ Mozilla Public License, version 2.0 fail to comply with any of its terms. However, if You become compliant, then the rights granted under this License from a particular Contributor are reinstated (a) provisionally, unless and until such Contributor - explicitly and finally terminates Your grants, and (b) on an ongoing - basis, if such Contributor fails to notify You of the non-compliance by - some reasonable means prior to 60 days after You have come back into - compliance. Moreover, Your grants from a particular Contributor are - reinstated on an ongoing basis if such Contributor notifies You of the - non-compliance by some reasonable means, this is the first time You have - received notice of non-compliance with this License from such - Contributor, and You become compliant prior to 30 days after Your receipt - of the notice. + explicitly and finally terminates Your grants, and (b) on an ongoing basis, + if such Contributor fails to notify You of the non-compliance by some + reasonable means prior to 60 days after You have come back into compliance. + Moreover, Your grants from a particular Contributor are reinstated on an + ongoing basis if such Contributor notifies You of the non-compliance by + some reasonable means, this is the first time You have received notice of + non-compliance with this License from such Contributor, and You become + compliant prior to 30 days after Your receipt of the notice. 5.2. If You initiate litigation against any entity by asserting a patent - infringement claim (excluding declaratory judgment actions, - counter-claims, and cross-claims) alleging that a Contributor Version - directly or indirectly infringes any patent, then the rights granted to - You by any and all Contributors for the Covered Software under Section - 2.1 of this License shall terminate. + infringement claim (excluding declaratory judgment actions, counter-claims, + and cross-claims) alleging that a Contributor Version directly or + indirectly infringes any patent, then the rights granted to You by any and + all Contributors for the Covered Software under Section 2.1 of this License + shall terminate. 5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user license agreements (excluding distributors and resellers) which have been @@ -11456,16 +10610,16 @@ Mozilla Public License, version 2.0 6. Disclaimer of Warranty - Covered Software is provided under this License on an "as is" basis, - without warranty of any kind, either expressed, implied, or statutory, - including, without limitation, warranties that the Covered Software is free - of defects, merchantable, fit for a particular purpose or non-infringing. - The entire risk as to the quality and performance of the Covered Software - is with You. Should any Covered Software prove defective in any respect, - You (not any Contributor) assume the cost of any necessary servicing, - repair, or correction. This disclaimer of warranty constitutes an essential - part of this License. No use of any Covered Software is authorized under - this License except under this disclaimer. + Covered Software is provided under this License on an “as is” basis, without + warranty of any kind, either expressed, implied, or statutory, including, + without limitation, warranties that the Covered Software is free of defects, + merchantable, fit for a particular purpose or non-infringing. The entire + risk as to the quality and performance of the Covered Software is with You. + Should any Covered Software prove defective in any respect, You (not any + Contributor) assume the cost of any necessary servicing, repair, or + correction. This disclaimer of warranty constitutes an essential part of this + License. No use of any Covered Software is authorized under this License + except under this disclaimer. 7. Limitation of Liability @@ -11477,29 +10631,27 @@ Mozilla Public License, version 2.0 goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses, even if such party shall have been informed of the possibility of such damages. This limitation of liability - shall not apply to liability for death or personal injury resulting from - such party's negligence to the extent applicable law prohibits such - limitation. Some jurisdictions do not allow the exclusion or limitation of - incidental or consequential damages, so this exclusion and limitation may - not apply to You. + shall not apply to liability for death or personal injury resulting from such + party’s negligence to the extent applicable law prohibits such limitation. + Some jurisdictions do not allow the exclusion or limitation of incidental or + consequential damages, so this exclusion and limitation may not apply to You. 8. Litigation - Any litigation relating to this License may be brought only in the courts - of a jurisdiction where the defendant maintains its principal place of - business and such litigation shall be governed by laws of that - jurisdiction, without reference to its conflict-of-law provisions. Nothing - in this Section shall prevent a party's ability to bring cross-claims or - counter-claims. + Any litigation relating to this License may be brought only in the courts of + a jurisdiction where the defendant maintains its principal place of business + and such litigation shall be governed by laws of that jurisdiction, without + reference to its conflict-of-law provisions. Nothing in this Section shall + prevent a party’s ability to bring cross-claims or counter-claims. 9. Miscellaneous - This License represents the complete agreement concerning the subject - matter hereof. If any provision of this License is held to be - unenforceable, such provision shall be reformed only to the extent - necessary to make it enforceable. Any law or regulation which provides that - the language of a contract shall be construed against the drafter shall not - be used to construe this License against a Contributor. + This License represents the complete agreement concerning the subject matter + hereof. If any provision of this License is held to be unenforceable, such + provision shall be reformed only to the extent necessary to make it + enforceable. Any law or regulation which provides that the language of a + contract shall be construed against the drafter shall not be used to construe + this License against a Contributor. 10. Versions of the License @@ -11513,24 +10665,23 @@ Mozilla Public License, version 2.0 10.2. Effect of New Versions - You may distribute the Covered Software under the terms of the version - of the License under which You originally received the Covered Software, - or under the terms of any subsequent version published by the license + You may distribute the Covered Software under the terms of the version of + the License under which You originally received the Covered Software, or + under the terms of any subsequent version published by the license steward. 10.3. Modified Versions If you create software not governed by this License, and you want to - create a new license for such software, you may create and use a - modified version of this License if you rename the license and remove - any references to the name of the license steward (except to note that - such modified license differs from this License). + create a new license for such software, you may create and use a modified + version of this License if you rename the license and remove any + references to the name of the license steward (except to note that such + modified license differs from this License). -10.4. Distributing Source Code Form that is Incompatible With Secondary - Licenses If You choose to distribute Source Code Form that is - Incompatible With Secondary Licenses under the terms of this version of - the License, the notice described in Exhibit B of this License must be - attached. +10.4. Distributing Source Code Form that is Incompatible With Secondary Licenses + If You choose to distribute Source Code Form that is Incompatible With + Secondary Licenses under the terms of this version of the License, the + notice described in Exhibit B of this License must be attached. Exhibit A - Source Code Form License Notice @@ -11541,1215 +10692,765 @@ Exhibit A - Source Code Form License Notice obtain one at http://mozilla.org/MPL/2.0/. -If it is not possible or desirable to put the notice in a particular file, -then You may include the notice in a location (such as a LICENSE file in a -relevant directory) where a recipient would be likely to look for such a -notice. +If it is not possible or desirable to put the notice in a particular file, then +You may include the notice in a location (such as a LICENSE file in a relevant +directory) where a recipient would be likely to look for such a notice. You may add additional accurate notices of copyright ownership. -Exhibit B - "Incompatible With Secondary Licenses" Notice +Exhibit B - “Incompatible With Secondary Licenses” Notice - This Source Code Form is "Incompatible - With Secondary Licenses", as defined by + This Source Code Form is “Incompatible + With Secondary Licenses”, as defined by the Mozilla Public License, v. 2.0. -------------------------------------------------------------------------------- -Dependency : github.com/inconshreveable/mousetrap -Version: v1.1.0 -Licence type (autodetected): Apache-2.0 +Dependency : github.com/hashicorp/go-multierror +Version: v1.1.1 +Licence type (autodetected): MPL-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/github.com/inconshreveable/mousetrap@v1.1.0/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/hashicorp/go-multierror@v1.1.1/LICENSE: - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ +Mozilla Public License, version 2.0 - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION +1. Definitions - 1. Definitions. +1.1. “Contributor” - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. + means each individual or legal entity that creates, contributes to the + creation of, or owns Covered Software. - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. +1.2. “Contributor Version” - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. + means the combination of the Contributions of others (if any) used by a + Contributor and that particular Contributor’s Contribution. - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. +1.3. “Contribution” - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. + means Covered Software of a particular Contributor. - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. +1.4. “Covered Software” - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). + means Source Code Form to which the initial Contributor has attached the + notice in Exhibit A, the Executable Form of such Source Code Form, and + Modifications of such Source Code Form, in each case including portions + thereof. - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. +1.5. “Incompatible With Secondary Licenses” + means - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." + a. that the initial Contributor has attached the notice described in + Exhibit B to the Covered Software; or - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. + b. that the Covered Software was made available under the terms of version + 1.1 or earlier of the License, but not also under the terms of a + Secondary License. - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. +1.6. “Executable Form” - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. + means any form of the work other than Source Code Form. - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: +1.7. “Larger Work” - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and + means a work that combines Covered Software with other material, in a separate + file or files, that is not Covered Software. - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and +1.8. “License” - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and + means this document. - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. +1.9. “Licensable” - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. + means having the right to grant, to the maximum extent possible, whether at the + time of the initial grant or subsequently, any and all of the rights conveyed by + this License. - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. +1.10. “Modifications” - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. + means any of the following: - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. + a. any file in Source Code Form that results from an addition to, deletion + from, or modification of the contents of Covered Software; or - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. + b. any new file in Source Code Form that contains any Covered Software. - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. +1.11. “Patent Claims” of a Contributor - END OF TERMS AND CONDITIONS + means any patent claim(s), including without limitation, method, process, + and apparatus claims, in any patent Licensable by such Contributor that + would be infringed, but for the grant of the License, by the making, + using, selling, offering for sale, having made, import, or transfer of + either its Contributions or its Contributor Version. - APPENDIX: How to apply the Apache License to your work. +1.12. “Secondary License” - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. + means either the GNU General Public License, Version 2.0, the GNU Lesser + General Public License, Version 2.1, the GNU Affero General Public + License, Version 3.0, or any later versions of those licenses. - Copyright 2022 Alan Shreve (@inconshreveable) +1.13. “Source Code Form” - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at + means the form of the work preferred for making modifications. - http://www.apache.org/licenses/LICENSE-2.0 +1.14. “You” (or “Your”) - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. + means an individual or a legal entity exercising rights under this + License. For legal entities, “You” includes any entity that controls, is + controlled by, or is under common control with You. For purposes of this + definition, “control” means (a) the power, direct or indirect, to cause + the direction or management of such entity, whether by contract or + otherwise, or (b) ownership of more than fifty percent (50%) of the + outstanding shares or beneficial ownership of such entity. --------------------------------------------------------------------------------- -Dependency : github.com/jcmturner/aescts/v2 -Version: v2.0.0 -Licence type (autodetected): Apache-2.0 --------------------------------------------------------------------------------- +2. License Grants and Conditions -Contents of probable licence file $GOMODCACHE/github.com/jcmturner/aescts/v2@v2.0.0/LICENSE: +2.1. Grants - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ + Each Contributor hereby grants You a world-wide, royalty-free, + non-exclusive license: - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + a. under intellectual property rights (other than patent or trademark) + Licensable by such Contributor to use, reproduce, make available, + modify, display, perform, distribute, and otherwise exploit its + Contributions, either on an unmodified basis, with Modifications, or as + part of a Larger Work; and - 1. Definitions. + b. under Patent Claims of such Contributor to make, use, sell, offer for + sale, have made, import, and otherwise transfer either its Contributions + or its Contributor Version. - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. +2.2. Effective Date - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. + The licenses granted in Section 2.1 with respect to any Contribution become + effective for each Contribution on the date the Contributor first distributes + such Contribution. - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. +2.3. Limitations on Grant Scope - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. + The licenses granted in this Section 2 are the only rights granted under this + License. No additional rights or licenses will be implied from the distribution + or licensing of Covered Software under this License. Notwithstanding Section + 2.1(b) above, no patent license is granted by a Contributor: - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. + a. for any code that a Contributor has removed from Covered Software; or - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. + b. for infringements caused by: (i) Your and any other third party’s + modifications of Covered Software, or (ii) the combination of its + Contributions with other software (except as part of its Contributor + Version); or - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). + c. under Patent Claims infringed by Covered Software in the absence of its + Contributions. - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. + This License does not grant any rights in the trademarks, service marks, or + logos of any Contributor (except as may be necessary to comply with the + notice requirements in Section 3.4). - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." +2.4. Subsequent Licenses - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. + No Contributor makes additional grants as a result of Your choice to + distribute the Covered Software under a subsequent version of this License + (see Section 10.2) or under the terms of a Secondary License (if permitted + under the terms of Section 3.3). - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. +2.5. Representation - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. + Each Contributor represents that the Contributor believes its Contributions + are its original creation(s) or it has sufficient rights to grant the + rights to its Contributions conveyed by this License. - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: +2.6. Fair Use - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and + This License is not intended to limit any rights You have under applicable + copyright doctrines of fair use, fair dealing, or other equivalents. - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and +2.7. Conditions - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and + Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in + Section 2.1. - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. +3. Responsibilities - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. +3.1. Distribution of Source Form - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. + All distribution of Covered Software in Source Code Form, including any + Modifications that You create or to which You contribute, must be under the + terms of this License. You must inform recipients that the Source Code Form + of the Covered Software is governed by the terms of this License, and how + they can obtain a copy of this License. You may not attempt to alter or + restrict the recipients’ rights in the Source Code Form. - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. +3.2. Distribution of Executable Form - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. + If You distribute Covered Software in Executable Form then: - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. + a. such Covered Software must also be made available in Source Code Form, + as described in Section 3.1, and You must inform recipients of the + Executable Form how they can obtain a copy of such Source Code Form by + reasonable means in a timely manner, at a charge no more than the cost + of distribution to the recipient; and - END OF TERMS AND CONDITIONS + b. You may distribute such Executable Form under the terms of this License, + or sublicense it under different terms, provided that the license for + the Executable Form does not attempt to limit or alter the recipients’ + rights in the Source Code Form under this License. - APPENDIX: How to apply the Apache License to your work. +3.3. Distribution of a Larger Work - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. + You may create and distribute a Larger Work under terms of Your choice, + provided that You also comply with the requirements of this License for the + Covered Software. If the Larger Work is a combination of Covered Software + with a work governed by one or more Secondary Licenses, and the Covered + Software is not Incompatible With Secondary Licenses, this License permits + You to additionally distribute such Covered Software under the terms of + such Secondary License(s), so that the recipient of the Larger Work may, at + their option, further distribute the Covered Software under the terms of + either this License or such Secondary License(s). - Copyright {yyyy} {name of copyright owner} +3.4. Notices - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at + You may not remove or alter the substance of any license notices (including + copyright notices, patent notices, disclaimers of warranty, or limitations + of liability) contained within the Source Code Form of the Covered + Software, except that You may alter any license notices to the extent + required to remedy known factual inaccuracies. - http://www.apache.org/licenses/LICENSE-2.0 +3.5. Application of Additional Terms - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. + You may choose to offer, and to charge a fee for, warranty, support, + indemnity or liability obligations to one or more recipients of Covered + Software. However, You may do so only on Your own behalf, and not on behalf + of any Contributor. You must make it absolutely clear that any such + warranty, support, indemnity, or liability obligation is offered by You + alone, and You hereby agree to indemnify every Contributor for any + liability incurred by such Contributor as a result of warranty, support, + indemnity or liability terms You offer. You may include additional + disclaimers of warranty and limitations of liability specific to any + jurisdiction. +4. Inability to Comply Due to Statute or Regulation --------------------------------------------------------------------------------- -Dependency : github.com/jcmturner/dnsutils/v2 -Version: v2.0.0 -Licence type (autodetected): Apache-2.0 --------------------------------------------------------------------------------- + If it is impossible for You to comply with any of the terms of this License + with respect to some or all of the Covered Software due to statute, judicial + order, or regulation then You must: (a) comply with the terms of this License + to the maximum extent possible; and (b) describe the limitations and the code + they affect. Such description must be placed in a text file included with all + distributions of the Covered Software under this License. Except to the + extent prohibited by statute or regulation, such description must be + sufficiently detailed for a recipient of ordinary skill to be able to + understand it. -Contents of probable licence file $GOMODCACHE/github.com/jcmturner/dnsutils/v2@v2.0.0/LICENSE: +5. Termination - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ +5.1. The rights granted under this License will terminate automatically if You + fail to comply with any of its terms. However, if You become compliant, + then the rights granted under this License from a particular Contributor + are reinstated (a) provisionally, unless and until such Contributor + explicitly and finally terminates Your grants, and (b) on an ongoing basis, + if such Contributor fails to notify You of the non-compliance by some + reasonable means prior to 60 days after You have come back into compliance. + Moreover, Your grants from a particular Contributor are reinstated on an + ongoing basis if such Contributor notifies You of the non-compliance by + some reasonable means, this is the first time You have received notice of + non-compliance with this License from such Contributor, and You become + compliant prior to 30 days after Your receipt of the notice. - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION +5.2. If You initiate litigation against any entity by asserting a patent + infringement claim (excluding declaratory judgment actions, counter-claims, + and cross-claims) alleging that a Contributor Version directly or + indirectly infringes any patent, then the rights granted to You by any and + all Contributors for the Covered Software under Section 2.1 of this License + shall terminate. - 1. Definitions. +5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user + license agreements (excluding distributors and resellers) which have been + validly granted by You or Your distributors under this License prior to + termination shall survive termination. - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. +6. Disclaimer of Warranty - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. + Covered Software is provided under this License on an “as is” basis, without + warranty of any kind, either expressed, implied, or statutory, including, + without limitation, warranties that the Covered Software is free of defects, + merchantable, fit for a particular purpose or non-infringing. The entire + risk as to the quality and performance of the Covered Software is with You. + Should any Covered Software prove defective in any respect, You (not any + Contributor) assume the cost of any necessary servicing, repair, or + correction. This disclaimer of warranty constitutes an essential part of this + License. No use of any Covered Software is authorized under this License + except under this disclaimer. - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. +7. Limitation of Liability - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. + Under no circumstances and under no legal theory, whether tort (including + negligence), contract, or otherwise, shall any Contributor, or anyone who + distributes Covered Software as permitted above, be liable to You for any + direct, indirect, special, incidental, or consequential damages of any + character including, without limitation, damages for lost profits, loss of + goodwill, work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses, even if such party shall have been + informed of the possibility of such damages. This limitation of liability + shall not apply to liability for death or personal injury resulting from such + party’s negligence to the extent applicable law prohibits such limitation. + Some jurisdictions do not allow the exclusion or limitation of incidental or + consequential damages, so this exclusion and limitation may not apply to You. - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. +8. Litigation - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. + Any litigation relating to this License may be brought only in the courts of + a jurisdiction where the defendant maintains its principal place of business + and such litigation shall be governed by laws of that jurisdiction, without + reference to its conflict-of-law provisions. Nothing in this Section shall + prevent a party’s ability to bring cross-claims or counter-claims. - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). +9. Miscellaneous - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. + This License represents the complete agreement concerning the subject matter + hereof. If any provision of this License is held to be unenforceable, such + provision shall be reformed only to the extent necessary to make it + enforceable. Any law or regulation which provides that the language of a + contract shall be construed against the drafter shall not be used to construe + this License against a Contributor. - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. +10. Versions of the License - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. +10.1. New Versions - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. + Mozilla Foundation is the license steward. Except as provided in Section + 10.3, no one other than the license steward has the right to modify or + publish new versions of this License. Each version will be given a + distinguishing version number. - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: +10.2. Effect of New Versions - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and + You may distribute the Covered Software under the terms of the version of + the License under which You originally received the Covered Software, or + under the terms of any subsequent version published by the license + steward. - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and +10.3. Modified Versions - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and + If you create software not governed by this License, and you want to + create a new license for such software, you may create and use a modified + version of this License if you rename the license and remove any + references to the name of the license steward (except to note that such + modified license differs from this License). - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. +10.4. Distributing Source Code Form that is Incompatible With Secondary Licenses + If You choose to distribute Source Code Form that is Incompatible With + Secondary Licenses under the terms of this version of the License, the + notice described in Exhibit B of this License must be attached. - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. +Exhibit A - Source Code Form License Notice - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. + This Source Code Form is subject to the + terms of the Mozilla Public License, v. + 2.0. If a copy of the MPL was not + distributed with this file, You can + obtain one at + http://mozilla.org/MPL/2.0/. - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. +If it is not possible or desirable to put the notice in a particular file, then +You may include the notice in a location (such as a LICENSE file in a relevant +directory) where a recipient would be likely to look for such a notice. - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. +You may add additional accurate notices of copyright ownership. - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. +Exhibit B - “Incompatible With Secondary Licenses” Notice - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. + This Source Code Form is “Incompatible + With Secondary Licenses”, as defined by + the Mozilla Public License, v. 2.0. - END OF TERMS AND CONDITIONS - APPENDIX: How to apply the Apache License to your work. +-------------------------------------------------------------------------------- +Dependency : github.com/hashicorp/go-uuid +Version: v1.0.3 +Licence type (autodetected): MPL-2.0 +-------------------------------------------------------------------------------- - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] +Contents of probable licence file $GOMODCACHE/github.com/hashicorp/go-uuid@v1.0.3/LICENSE: - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at +Copyright © 2015-2022 HashiCorp, Inc. - http://www.apache.org/licenses/LICENSE-2.0 +Mozilla Public License, version 2.0 - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. +1. Definitions +1.1. "Contributor" --------------------------------------------------------------------------------- -Dependency : github.com/jcmturner/gofork -Version: v1.7.6 -Licence type (autodetected): BSD-3-Clause --------------------------------------------------------------------------------- + means each individual or legal entity that creates, contributes to the + creation of, or owns Covered Software. -Contents of probable licence file $GOMODCACHE/github.com/jcmturner/gofork@v1.7.6/LICENSE: +1.2. "Contributor Version" -Copyright (c) 2009 The Go Authors. All rights reserved. + means the combination of the Contributions of others (if any) used by a + Contributor and that particular Contributor's Contribution. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: +1.3. "Contribution" - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. + means Covered Software of a particular Contributor. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +1.4. "Covered Software" + means Source Code Form to which the initial Contributor has attached the + notice in Exhibit A, the Executable Form of such Source Code Form, and + Modifications of such Source Code Form, in each case including portions + thereof. --------------------------------------------------------------------------------- -Dependency : github.com/jcmturner/gokrb5/v8 -Version: v8.4.4 -Licence type (autodetected): Apache-2.0 --------------------------------------------------------------------------------- +1.5. "Incompatible With Secondary Licenses" + means -Contents of probable licence file $GOMODCACHE/github.com/jcmturner/gokrb5/v8@v8.4.4/LICENSE: + a. that the initial Contributor has attached the notice described in + Exhibit B to the Covered Software; or - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ + b. that the Covered Software was made available under the terms of + version 1.1 or earlier of the License, but not also under the terms of + a Secondary License. - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION +1.6. "Executable Form" - 1. Definitions. + means any form of the work other than Source Code Form. - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. +1.7. "Larger Work" - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. + means a work that combines Covered Software with other material, in a + separate file or files, that is not Covered Software. - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. +1.8. "License" - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. + means this document. - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. +1.9. "Licensable" - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. + means having the right to grant, to the maximum extent possible, whether + at the time of the initial grant or subsequently, any and all of the + rights conveyed by this License. - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). +1.10. "Modifications" - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. + means any of the following: - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." + a. any file in Source Code Form that results from an addition to, + deletion from, or modification of the contents of Covered Software; or - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. + b. any new file in Source Code Form that contains any Covered Software. - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. +1.11. "Patent Claims" of a Contributor - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. + means any patent claim(s), including without limitation, method, + process, and apparatus claims, in any patent Licensable by such + Contributor that would be infringed, but for the grant of the License, + by the making, using, selling, offering for sale, having made, import, + or transfer of either its Contributions or its Contributor Version. - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: +1.12. "Secondary License" - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and + means either the GNU General Public License, Version 2.0, the GNU Lesser + General Public License, Version 2.1, the GNU Affero General Public + License, Version 3.0, or any later versions of those licenses. - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and +1.13. "Source Code Form" - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and + means the form of the work preferred for making modifications. - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. +1.14. "You" (or "Your") - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. + means an individual or a legal entity exercising rights under this + License. For legal entities, "You" includes any entity that controls, is + controlled by, or is under common control with You. For purposes of this + definition, "control" means (a) the power, direct or indirect, to cause + the direction or management of such entity, whether by contract or + otherwise, or (b) ownership of more than fifty percent (50%) of the + outstanding shares or beneficial ownership of such entity. - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. +2. License Grants and Conditions - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. +2.1. Grants - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. + Each Contributor hereby grants You a world-wide, royalty-free, + non-exclusive license: - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. + a. under intellectual property rights (other than patent or trademark) + Licensable by such Contributor to use, reproduce, make available, + modify, display, perform, distribute, and otherwise exploit its + Contributions, either on an unmodified basis, with Modifications, or + as part of a Larger Work; and - END OF TERMS AND CONDITIONS + b. under Patent Claims of such Contributor to make, use, sell, offer for + sale, have made, import, and otherwise transfer either its + Contributions or its Contributor Version. - APPENDIX: How to apply the Apache License to your work. +2.2. Effective Date - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. + The licenses granted in Section 2.1 with respect to any Contribution + become effective for each Contribution on the date the Contributor first + distributes such Contribution. - Copyright {yyyy} {name of copyright owner} +2.3. Limitations on Grant Scope - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at + The licenses granted in this Section 2 are the only rights granted under + this License. No additional rights or licenses will be implied from the + distribution or licensing of Covered Software under this License. + Notwithstanding Section 2.1(b) above, no patent license is granted by a + Contributor: - http://www.apache.org/licenses/LICENSE-2.0 + a. for any code that a Contributor has removed from Covered Software; or - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. + b. for infringements caused by: (i) Your and any other third party's + modifications of Covered Software, or (ii) the combination of its + Contributions with other software (except as part of its Contributor + Version); or + c. under Patent Claims infringed by Covered Software in the absence of + its Contributions. --------------------------------------------------------------------------------- -Dependency : github.com/jcmturner/rpc/v2 -Version: v2.0.3 -Licence type (autodetected): Apache-2.0 --------------------------------------------------------------------------------- + This License does not grant any rights in the trademarks, service marks, + or logos of any Contributor (except as may be necessary to comply with + the notice requirements in Section 3.4). -Contents of probable licence file $GOMODCACHE/github.com/jcmturner/rpc/v2@v2.0.3/LICENSE: +2.4. Subsequent Licenses - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ + No Contributor makes additional grants as a result of Your choice to + distribute the Covered Software under a subsequent version of this + License (see Section 10.2) or under the terms of a Secondary License (if + permitted under the terms of Section 3.3). - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION +2.5. Representation - 1. Definitions. + Each Contributor represents that the Contributor believes its + Contributions are its original creation(s) or it has sufficient rights to + grant the rights to its Contributions conveyed by this License. - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. +2.6. Fair Use - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. + This License is not intended to limit any rights You have under + applicable copyright doctrines of fair use, fair dealing, or other + equivalents. - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. +2.7. Conditions - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. + Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in + Section 2.1. - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. +3. Responsibilities - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). +3.1. Distribution of Source Form - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. + All distribution of Covered Software in Source Code Form, including any + Modifications that You create or to which You contribute, must be under + the terms of this License. You must inform recipients that the Source + Code Form of the Covered Software is governed by the terms of this + License, and how they can obtain a copy of this License. You may not + attempt to alter or restrict the recipients' rights in the Source Code + Form. - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." +3.2. Distribution of Executable Form - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. + If You distribute Covered Software in Executable Form then: - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. + a. such Covered Software must also be made available in Source Code Form, + as described in Section 3.1, and You must inform recipients of the + Executable Form how they can obtain a copy of such Source Code Form by + reasonable means in a timely manner, at a charge no more than the cost + of distribution to the recipient; and - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. + b. You may distribute such Executable Form under the terms of this + License, or sublicense it under different terms, provided that the + license for the Executable Form does not attempt to limit or alter the + recipients' rights in the Source Code Form under this License. - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: +3.3. Distribution of a Larger Work - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and + You may create and distribute a Larger Work under terms of Your choice, + provided that You also comply with the requirements of this License for + the Covered Software. If the Larger Work is a combination of Covered + Software with a work governed by one or more Secondary Licenses, and the + Covered Software is not Incompatible With Secondary Licenses, this + License permits You to additionally distribute such Covered Software + under the terms of such Secondary License(s), so that the recipient of + the Larger Work may, at their option, further distribute the Covered + Software under the terms of either this License or such Secondary + License(s). - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and +3.4. Notices - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and + You may not remove or alter the substance of any license notices + (including copyright notices, patent notices, disclaimers of warranty, or + limitations of liability) contained within the Source Code Form of the + Covered Software, except that You may alter any license notices to the + extent required to remedy known factual inaccuracies. - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. +3.5. Application of Additional Terms - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. + You may choose to offer, and to charge a fee for, warranty, support, + indemnity or liability obligations to one or more recipients of Covered + Software. However, You may do so only on Your own behalf, and not on + behalf of any Contributor. You must make it absolutely clear that any + such warranty, support, indemnity, or liability obligation is offered by + You alone, and You hereby agree to indemnify every Contributor for any + liability incurred by such Contributor as a result of warranty, support, + indemnity or liability terms You offer. You may include additional + disclaimers of warranty and limitations of liability specific to any + jurisdiction. - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. +4. Inability to Comply Due to Statute or Regulation - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. + If it is impossible for You to comply with any of the terms of this License + with respect to some or all of the Covered Software due to statute, + judicial order, or regulation then You must: (a) comply with the terms of + this License to the maximum extent possible; and (b) describe the + limitations and the code they affect. Such description must be placed in a + text file included with all distributions of the Covered Software under + this License. Except to the extent prohibited by statute or regulation, + such description must be sufficiently detailed for a recipient of ordinary + skill to be able to understand it. - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. +5. Termination - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. +5.1. The rights granted under this License will terminate automatically if You + fail to comply with any of its terms. However, if You become compliant, + then the rights granted under this License from a particular Contributor + are reinstated (a) provisionally, unless and until such Contributor + explicitly and finally terminates Your grants, and (b) on an ongoing + basis, if such Contributor fails to notify You of the non-compliance by + some reasonable means prior to 60 days after You have come back into + compliance. Moreover, Your grants from a particular Contributor are + reinstated on an ongoing basis if such Contributor notifies You of the + non-compliance by some reasonable means, this is the first time You have + received notice of non-compliance with this License from such + Contributor, and You become compliant prior to 30 days after Your receipt + of the notice. - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. +5.2. If You initiate litigation against any entity by asserting a patent + infringement claim (excluding declaratory judgment actions, + counter-claims, and cross-claims) alleging that a Contributor Version + directly or indirectly infringes any patent, then the rights granted to + You by any and all Contributors for the Covered Software under Section + 2.1 of this License shall terminate. - END OF TERMS AND CONDITIONS +5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user + license agreements (excluding distributors and resellers) which have been + validly granted by You or Your distributors under this License prior to + termination shall survive termination. - APPENDIX: How to apply the Apache License to your work. +6. Disclaimer of Warranty - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. + Covered Software is provided under this License on an "as is" basis, + without warranty of any kind, either expressed, implied, or statutory, + including, without limitation, warranties that the Covered Software is free + of defects, merchantable, fit for a particular purpose or non-infringing. + The entire risk as to the quality and performance of the Covered Software + is with You. Should any Covered Software prove defective in any respect, + You (not any Contributor) assume the cost of any necessary servicing, + repair, or correction. This disclaimer of warranty constitutes an essential + part of this License. No use of any Covered Software is authorized under + this License except under this disclaimer. - Copyright [yyyy] [name of copyright owner] +7. Limitation of Liability - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at + Under no circumstances and under no legal theory, whether tort (including + negligence), contract, or otherwise, shall any Contributor, or anyone who + distributes Covered Software as permitted above, be liable to You for any + direct, indirect, special, incidental, or consequential damages of any + character including, without limitation, damages for lost profits, loss of + goodwill, work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses, even if such party shall have been + informed of the possibility of such damages. This limitation of liability + shall not apply to liability for death or personal injury resulting from + such party's negligence to the extent applicable law prohibits such + limitation. Some jurisdictions do not allow the exclusion or limitation of + incidental or consequential damages, so this exclusion and limitation may + not apply to You. - http://www.apache.org/licenses/LICENSE-2.0 +8. Litigation - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. + Any litigation relating to this License may be brought only in the courts + of a jurisdiction where the defendant maintains its principal place of + business and such litigation shall be governed by laws of that + jurisdiction, without reference to its conflict-of-law provisions. Nothing + in this Section shall prevent a party's ability to bring cross-claims or + counter-claims. +9. Miscellaneous --------------------------------------------------------------------------------- -Dependency : github.com/joeshaw/multierror -Version: v0.0.0-20140124173710-69b34d4ec901 -Licence type (autodetected): MIT --------------------------------------------------------------------------------- + This License represents the complete agreement concerning the subject + matter hereof. If any provision of this License is held to be + unenforceable, such provision shall be reformed only to the extent + necessary to make it enforceable. Any law or regulation which provides that + the language of a contract shall be construed against the drafter shall not + be used to construe this License against a Contributor. -Contents of probable licence file $GOMODCACHE/github.com/joeshaw/multierror@v0.0.0-20140124173710-69b34d4ec901/LICENSE: -The MIT License (MIT) +10. Versions of the License -Copyright (c) 2014 Joe Shaw +10.1. New Versions -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: + Mozilla Foundation is the license steward. Except as provided in Section + 10.3, no one other than the license steward has the right to modify or + publish new versions of this License. Each version will be given a + distinguishing version number. -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. +10.2. Effect of New Versions -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. + You may distribute the Covered Software under the terms of the version + of the License under which You originally received the Covered Software, + or under the terms of any subsequent version published by the license + steward. +10.3. Modified Versions --------------------------------------------------------------------------------- -Dependency : github.com/json-iterator/go -Version: v1.1.12 -Licence type (autodetected): MIT --------------------------------------------------------------------------------- + If you create software not governed by this License, and you want to + create a new license for such software, you may create and use a + modified version of this License if you rename the license and remove + any references to the name of the license steward (except to note that + such modified license differs from this License). -Contents of probable licence file $GOMODCACHE/github.com/json-iterator/go@v1.1.12/LICENSE: +10.4. Distributing Source Code Form that is Incompatible With Secondary + Licenses If You choose to distribute Source Code Form that is + Incompatible With Secondary Licenses under the terms of this version of + the License, the notice described in Exhibit B of this License must be + attached. -MIT License +Exhibit A - Source Code Form License Notice -Copyright (c) 2016 json-iterator + This Source Code Form is subject to the + terms of the Mozilla Public License, v. + 2.0. If a copy of the MPL was not + distributed with this file, You can + obtain one at + http://mozilla.org/MPL/2.0/. -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: +If it is not possible or desirable to put the notice in a particular file, +then You may include the notice in a location (such as a LICENSE file in a +relevant directory) where a recipient would be likely to look for such a +notice. -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. +You may add additional accurate notices of copyright ownership. + +Exhibit B - "Incompatible With Secondary Licenses" Notice + + This Source Code Form is "Incompatible + With Secondary Licenses", as defined by + the Mozilla Public License, v. 2.0. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -------------------------------------------------------------------------------- -Dependency : github.com/klauspost/compress -Version: v1.17.9 +Dependency : github.com/inconshreveable/mousetrap +Version: v1.1.0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/github.com/klauspost/compress@v1.17.9/LICENSE: - -Copyright (c) 2012 The Go Authors. All rights reserved. -Copyright (c) 2019 Klaus Post. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ------------------- - -Files: gzhttp/* +Contents of probable licence file $GOMODCACHE/github.com/inconshreveable/mousetrap@v1.1.0/LICENSE: Apache License Version 2.0, January 2004 @@ -12939,7 +11640,7 @@ Files: gzhttp/* same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright 2016-2017 The New York Times Company + Copyright 2022 Alan Shreve (@inconshreveable) Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -12953,229 +11654,20 @@ Files: gzhttp/* See the License for the specific language governing permissions and limitations under the License. ------------------- -Files: s2/cmd/internal/readahead/* +-------------------------------------------------------------------------------- +Dependency : github.com/jcmturner/aescts/v2 +Version: v2.0.0 +Licence type (autodetected): Apache-2.0 +-------------------------------------------------------------------------------- -The MIT License (MIT) +Contents of probable licence file $GOMODCACHE/github.com/jcmturner/aescts/v2@v2.0.0/LICENSE: -Copyright (c) 2015 Klaus Post + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - ---------------------- -Files: snappy/* -Files: internal/snapref/* - -Copyright (c) 2011 The Snappy-Go Authors. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ------------------ - -Files: s2/cmd/internal/filepathx/* - -Copyright 2016 The filepathx Authors - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - --------------------------------------------------------------------------------- -Dependency : github.com/kr/pretty -Version: v0.3.1 -Licence type (autodetected): MIT --------------------------------------------------------------------------------- - -Contents of probable licence file $GOMODCACHE/github.com/kr/pretty@v0.3.1/License: - -Copyright 2012 Keith Rarick - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - - --------------------------------------------------------------------------------- -Dependency : github.com/kr/text -Version: v0.2.0 -Licence type (autodetected): MIT --------------------------------------------------------------------------------- - -Contents of probable licence file $GOMODCACHE/github.com/kr/text@v0.2.0/License: - -Copyright 2012 Keith Rarick - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - - --------------------------------------------------------------------------------- -Dependency : github.com/mattn/go-colorable -Version: v0.1.13 -Licence type (autodetected): MIT --------------------------------------------------------------------------------- - -Contents of probable licence file $GOMODCACHE/github.com/mattn/go-colorable@v0.1.13/LICENSE: - -The MIT License (MIT) - -Copyright (c) 2016 Yasuhiro Matsumoto - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - - --------------------------------------------------------------------------------- -Dependency : github.com/mattn/go-isatty -Version: v0.0.20 -Licence type (autodetected): MIT --------------------------------------------------------------------------------- - -Contents of probable licence file $GOMODCACHE/github.com/mattn/go-isatty@v0.0.20/LICENSE: - -Copyright (c) Yasuhiro MATSUMOTO - -MIT License (Expat) - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - --------------------------------------------------------------------------------- -Dependency : github.com/mitchellh/hashstructure -Version: v1.1.0 -Licence type (autodetected): MIT --------------------------------------------------------------------------------- - -Contents of probable licence file $GOMODCACHE/github.com/mitchellh/hashstructure@v1.1.0/LICENSE: - -The MIT License (MIT) - -Copyright (c) 2016 Mitchell Hashimoto - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - - --------------------------------------------------------------------------------- -Dependency : github.com/modern-go/concurrent -Version: v0.0.0-20180306012644-bacd9c7ef1dd -Licence type (autodetected): Apache-2.0 --------------------------------------------------------------------------------- - -Contents of probable licence file $GOMODCACHE/github.com/modern-go/concurrent@v0.0.0-20180306012644-bacd9c7ef1dd/LICENSE: - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. @@ -13351,7 +11843,7 @@ Contents of probable licence file $GOMODCACHE/github.com/modern-go/concurrent@v0 APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" + boilerplate notice, with the fields enclosed by brackets "{}" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a @@ -13359,7 +11851,7 @@ Contents of probable licence file $GOMODCACHE/github.com/modern-go/concurrent@v0 same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright [yyyy] [name of copyright owner] + Copyright {yyyy} {name of copyright owner} Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -13375,67 +11867,26 @@ Contents of probable licence file $GOMODCACHE/github.com/modern-go/concurrent@v0 -------------------------------------------------------------------------------- -Dependency : github.com/munnerz/goautoneg -Version: v0.0.0-20191010083416-a7dc8b61c822 -Licence type (autodetected): BSD-3-Clause +Dependency : github.com/jcmturner/dnsutils/v2 +Version: v2.0.0 +Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/github.com/munnerz/goautoneg@v0.0.0-20191010083416-a7dc8b61c822/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/jcmturner/dnsutils/v2@v2.0.0/LICENSE: -Copyright (c) 2011, Open Knowledge Foundation Ltd. -All rights reserved. + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. + 1. Definitions. - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. - Neither the name of the Open Knowledge Foundation Ltd. nor the - names of its contributors may be used to endorse or promote - products derived from this software without specific prior written - permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - --------------------------------------------------------------------------------- -Dependency : github.com/open-telemetry/opentelemetry-collector-contrib/internal/coreinternal -Version: v0.109.0 -Licence type (autodetected): Apache-2.0 --------------------------------------------------------------------------------- - -Contents of probable licence file $GOMODCACHE/github.com/open-telemetry/opentelemetry-collector-contrib/internal/coreinternal@v0.109.0/LICENSE: - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common @@ -13627,92 +12078,14 @@ Contents of probable licence file $GOMODCACHE/github.com/open-telemetry/opentele -------------------------------------------------------------------------------- -Dependency : github.com/pierrec/lz4 -Version: v2.6.1+incompatible -Licence type (autodetected): BSD-3-Clause --------------------------------------------------------------------------------- - -Contents of probable licence file $GOMODCACHE/github.com/pierrec/lz4@v2.6.1+incompatible/LICENSE: - -Copyright (c) 2015, Pierre Curto -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -* Neither the name of xxHash nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - - --------------------------------------------------------------------------------- -Dependency : github.com/pierrec/lz4/v4 -Version: v4.1.21 -Licence type (autodetected): BSD-3-Clause --------------------------------------------------------------------------------- - -Contents of probable licence file $GOMODCACHE/github.com/pierrec/lz4/v4@v4.1.21/LICENSE: - -Copyright (c) 2015, Pierre Curto -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -* Neither the name of xxHash nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - - --------------------------------------------------------------------------------- -Dependency : github.com/planetscale/vtprotobuf -Version: v0.6.1-0.20240319094008-0393e58bdf10 +Dependency : github.com/jcmturner/gofork +Version: v1.7.6 Licence type (autodetected): BSD-3-Clause -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/github.com/planetscale/vtprotobuf@v0.6.1-0.20240319094008-0393e58bdf10/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/jcmturner/gofork@v1.7.6/LICENSE: -Copyright (c) 2021, PlanetScale Inc. All rights reserved. -Copyright (c) 2013, The GoGo Authors. All rights reserved. -Copyright (c) 2018 The Go Authors. All rights reserved. +Copyright (c) 2009 The Go Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are @@ -13742,12 +12115,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- -Dependency : github.com/prometheus/client_golang -Version: v1.20.2 +Dependency : github.com/jcmturner/goidentity/v6 +Version: v6.0.1 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/github.com/prometheus/client_golang@v1.20.2/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/jcmturner/goidentity/v6@v6.0.1/LICENSE: Apache License Version 2.0, January 2004 @@ -13929,7 +12302,7 @@ Contents of probable licence file $GOMODCACHE/github.com/prometheus/client_golan APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" + boilerplate notice, with the fields enclosed by brackets "{}" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a @@ -13937,7 +12310,7 @@ Contents of probable licence file $GOMODCACHE/github.com/prometheus/client_golan same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright [yyyy] [name of copyright owner] + Copyright {yyyy} {name of copyright owner} Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -13953,12 +12326,12 @@ Contents of probable licence file $GOMODCACHE/github.com/prometheus/client_golan -------------------------------------------------------------------------------- -Dependency : github.com/prometheus/client_model -Version: v0.6.1 +Dependency : github.com/jcmturner/gokrb5/v8 +Version: v8.4.4 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/github.com/prometheus/client_model@v0.6.1/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/jcmturner/gokrb5/v8@v8.4.4/LICENSE: Apache License Version 2.0, January 2004 @@ -14140,7 +12513,7 @@ Contents of probable licence file $GOMODCACHE/github.com/prometheus/client_model APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" + boilerplate notice, with the fields enclosed by brackets "{}" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a @@ -14148,7 +12521,7 @@ Contents of probable licence file $GOMODCACHE/github.com/prometheus/client_model same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright [yyyy] [name of copyright owner] + Copyright {yyyy} {name of copyright owner} Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14164,12 +12537,12 @@ Contents of probable licence file $GOMODCACHE/github.com/prometheus/client_model -------------------------------------------------------------------------------- -Dependency : github.com/prometheus/common -Version: v0.57.0 +Dependency : github.com/jcmturner/rpc/v2 +Version: v2.0.3 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/github.com/prometheus/common@v0.57.0/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/jcmturner/rpc/v2@v2.0.3/LICENSE: Apache License Version 2.0, January 2004 @@ -14375,12 +12748,76 @@ Contents of probable licence file $GOMODCACHE/github.com/prometheus/common@v0.57 -------------------------------------------------------------------------------- -Dependency : github.com/prometheus/procfs -Version: v0.15.1 +Dependency : github.com/json-iterator/go +Version: v1.1.12 +Licence type (autodetected): MIT +-------------------------------------------------------------------------------- + +Contents of probable licence file $GOMODCACHE/github.com/json-iterator/go@v1.1.12/LICENSE: + +MIT License + +Copyright (c) 2016 json-iterator + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + +-------------------------------------------------------------------------------- +Dependency : github.com/klauspost/compress +Version: v1.17.11 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/github.com/prometheus/procfs@v0.15.1/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/klauspost/compress@v1.17.11/LICENSE: + +Copyright (c) 2012 The Go Authors. All rights reserved. +Copyright (c) 2019 Klaus Post. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +------------------ + +Files: gzhttp/* Apache License Version 2.0, January 2004 @@ -14570,7 +13007,7 @@ Contents of probable licence file $GOMODCACHE/github.com/prometheus/procfs@v0.15 same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright [yyyy] [name of copyright owner] + Copyright 2016-2017 The New York Times Company Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14584,55 +13021,37 @@ Contents of probable licence file $GOMODCACHE/github.com/prometheus/procfs@v0.15 See the License for the specific language governing permissions and limitations under the License. +------------------ --------------------------------------------------------------------------------- -Dependency : github.com/rcrowley/go-metrics -Version: v0.0.0-20201227073835-cf1acfcdf475 -Licence type (autodetected): BSD-2-Clause-FreeBSD --------------------------------------------------------------------------------- - -Contents of probable licence file $GOMODCACHE/github.com/rcrowley/go-metrics@v0.0.0-20201227073835-cf1acfcdf475/LICENSE: - -Copyright 2012 Richard Crowley. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. +Files: s2/cmd/internal/readahead/* - 2. Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials provided - with the distribution. +The MIT License (MIT) -THIS SOFTWARE IS PROVIDED BY RICHARD CROWLEY ``AS IS'' AND ANY EXPRESS -OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL RICHARD CROWLEY OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF -THE POSSIBILITY OF SUCH DAMAGE. +Copyright (c) 2015 Klaus Post -The views and conclusions contained in the software and documentation -are those of the authors and should not be interpreted as representing -official policies, either expressed or implied, of Richard Crowley. +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. --------------------------------------------------------------------------------- -Dependency : github.com/rogpeppe/go-internal -Version: v1.12.0 -Licence type (autodetected): BSD-3-Clause --------------------------------------------------------------------------------- +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. -Contents of probable licence file $GOMODCACHE/github.com/rogpeppe/go-internal@v1.12.0/LICENSE: +--------------------- +Files: snappy/* +Files: internal/snapref/* -Copyright (c) 2018 The Go Authors. All rights reserved. +Copyright (c) 2011 The Snappy-Go Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are @@ -14660,567 +13079,992 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +----------------- --------------------------------------------------------------------------------- -Dependency : github.com/shirou/gopsutil/v3 -Version: v3.24.5 -Licence type (autodetected): BSD-3-Clause --------------------------------------------------------------------------------- - -Contents of probable licence file $GOMODCACHE/github.com/shirou/gopsutil/v3@v3.24.5/LICENSE: - -gopsutil is distributed under BSD license reproduced below. +Files: s2/cmd/internal/filepathx/* -Copyright (c) 2014, WAKAYAMA Shirou -All rights reserved. +Copyright 2016 The filepathx Authors -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - * Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - * Neither the name of the gopsutil authors nor the names of its contributors - may be used to endorse or promote products derived from this software without - specific prior written permission. +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------- -internal/common/binary.go in the gopsutil is copied and modified from golang/encoding/binary.go. +-------------------------------------------------------------------------------- +Dependency : github.com/kr/pretty +Version: v0.3.1 +Licence type (autodetected): MIT +-------------------------------------------------------------------------------- +Contents of probable licence file $GOMODCACHE/github.com/kr/pretty@v0.3.1/License: +Copyright 2012 Keith Rarick -Copyright (c) 2009 The Go Authors. All rights reserved. +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- -Dependency : github.com/shirou/gopsutil/v4 -Version: v4.24.7 -Licence type (autodetected): BSD-3-Clause +Dependency : github.com/kr/text +Version: v0.2.0 +Licence type (autodetected): MIT -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/github.com/shirou/gopsutil/v4@v4.24.7/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/kr/text@v0.2.0/License: -gopsutil is distributed under BSD license reproduced below. +Copyright 2012 Keith Rarick -Copyright (c) 2014, WAKAYAMA Shirou -All rights reserved. +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. - * Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - * Neither the name of the gopsutil authors nor the names of its contributors - may be used to endorse or promote products derived from this software without - specific prior written permission. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +-------------------------------------------------------------------------------- +Dependency : github.com/mattn/go-colorable +Version: v0.1.13 +Licence type (autodetected): MIT +-------------------------------------------------------------------------------- -------- -internal/common/binary.go in the gopsutil is copied and modified from golang/encoding/binary.go. +Contents of probable licence file $GOMODCACHE/github.com/mattn/go-colorable@v0.1.13/LICENSE: +The MIT License (MIT) +Copyright (c) 2016 Yasuhiro Matsumoto -Copyright (c) 2009 The Go Authors. All rights reserved. +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- -Dependency : github.com/shoenig/go-m1cpu -Version: v0.1.6 -Licence type (autodetected): MPL-2.0 +Dependency : github.com/mattn/go-isatty +Version: v0.0.20 +Licence type (autodetected): MIT -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/github.com/shoenig/go-m1cpu@v0.1.6/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/mattn/go-isatty@v0.0.20/LICENSE: -Mozilla Public License, version 2.0 +Copyright (c) Yasuhiro MATSUMOTO -1. Definitions +MIT License (Expat) -1.1. "Contributor" +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - means each individual or legal entity that creates, contributes to the - creation of, or owns Covered Software. +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. -1.2. "Contributor Version" +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - means the combination of the Contributions of others (if any) used by a - Contributor and that particular Contributor's Contribution. -1.3. "Contribution" +-------------------------------------------------------------------------------- +Dependency : github.com/mitchellh/hashstructure +Version: v1.1.0 +Licence type (autodetected): MIT +-------------------------------------------------------------------------------- - means Covered Software of a particular Contributor. +Contents of probable licence file $GOMODCACHE/github.com/mitchellh/hashstructure@v1.1.0/LICENSE: -1.4. "Covered Software" +The MIT License (MIT) - means Source Code Form to which the initial Contributor has attached the - notice in Exhibit A, the Executable Form of such Source Code Form, and - Modifications of such Source Code Form, in each case including portions - thereof. +Copyright (c) 2016 Mitchell Hashimoto -1.5. "Incompatible With Secondary Licenses" - means +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: - a. that the initial Contributor has attached the notice described in - Exhibit B to the Covered Software; or +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. - b. that the Covered Software was made available under the terms of - version 1.1 or earlier of the License, but not also under the terms of - a Secondary License. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. -1.6. "Executable Form" - means any form of the work other than Source Code Form. +-------------------------------------------------------------------------------- +Dependency : github.com/modern-go/concurrent +Version: v0.0.0-20180306012644-bacd9c7ef1dd +Licence type (autodetected): Apache-2.0 +-------------------------------------------------------------------------------- -1.7. "Larger Work" +Contents of probable licence file $GOMODCACHE/github.com/modern-go/concurrent@v0.0.0-20180306012644-bacd9c7ef1dd/LICENSE: - means a work that combines Covered Software with other material, in a - separate file or files, that is not Covered Software. + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ -1.8. "License" + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - means this document. + 1. Definitions. -1.9. "Licensable" + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. - means having the right to grant, to the maximum extent possible, whether - at the time of the initial grant or subsequently, any and all of the - rights conveyed by this License. + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. -1.10. "Modifications" + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. - means any of the following: + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. - a. any file in Source Code Form that results from an addition to, - deletion from, or modification of the contents of Covered Software; or + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. - b. any new file in Source Code Form that contains any Covered Software. + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. -1.11. "Patent Claims" of a Contributor + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). - means any patent claim(s), including without limitation, method, - process, and apparatus claims, in any patent Licensable by such - Contributor that would be infringed, but for the grant of the License, - by the making, using, selling, offering for sale, having made, import, - or transfer of either its Contributions or its Contributor Version. + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. -1.12. "Secondary License" + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." - means either the GNU General Public License, Version 2.0, the GNU Lesser - General Public License, Version 2.1, the GNU Affero General Public - License, Version 3.0, or any later versions of those licenses. + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. -1.13. "Source Code Form" + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. - means the form of the work preferred for making modifications. + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. -1.14. "You" (or "Your") + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: - means an individual or a legal entity exercising rights under this - License. For legal entities, "You" includes any entity that controls, is - controlled by, or is under common control with You. For purposes of this - definition, "control" means (a) the power, direct or indirect, to cause - the direction or management of such entity, whether by contract or - otherwise, or (b) ownership of more than fifty percent (50%) of the - outstanding shares or beneficial ownership of such entity. + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and -2. License Grants and Conditions + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and -2.1. Grants + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. - Each Contributor hereby grants You a world-wide, royalty-free, - non-exclusive license: + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. - a. under intellectual property rights (other than patent or trademark) - Licensable by such Contributor to use, reproduce, make available, - modify, display, perform, distribute, and otherwise exploit its - Contributions, either on an unmodified basis, with Modifications, or - as part of a Larger Work; and + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. - b. under Patent Claims of such Contributor to make, use, sell, offer for - sale, have made, import, and otherwise transfer either its - Contributions or its Contributor Version. + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. -2.2. Effective Date + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. - The licenses granted in Section 2.1 with respect to any Contribution - become effective for each Contribution on the date the Contributor first - distributes such Contribution. + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. -2.3. Limitations on Grant Scope + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. - The licenses granted in this Section 2 are the only rights granted under - this License. No additional rights or licenses will be implied from the - distribution or licensing of Covered Software under this License. - Notwithstanding Section 2.1(b) above, no patent license is granted by a - Contributor: + END OF TERMS AND CONDITIONS - a. for any code that a Contributor has removed from Covered Software; or + APPENDIX: How to apply the Apache License to your work. - b. for infringements caused by: (i) Your and any other third party's - modifications of Covered Software, or (ii) the combination of its - Contributions with other software (except as part of its Contributor - Version); or + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. - c. under Patent Claims infringed by Covered Software in the absence of - its Contributions. + Copyright [yyyy] [name of copyright owner] - This License does not grant any rights in the trademarks, service marks, - or logos of any Contributor (except as may be necessary to comply with - the notice requirements in Section 3.4). + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at -2.4. Subsequent Licenses + http://www.apache.org/licenses/LICENSE-2.0 - No Contributor makes additional grants as a result of Your choice to - distribute the Covered Software under a subsequent version of this - License (see Section 10.2) or under the terms of a Secondary License (if - permitted under the terms of Section 3.3). + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. -2.5. Representation - Each Contributor represents that the Contributor believes its - Contributions are its original creation(s) or it has sufficient rights to - grant the rights to its Contributions conveyed by this License. +-------------------------------------------------------------------------------- +Dependency : github.com/munnerz/goautoneg +Version: v0.0.0-20191010083416-a7dc8b61c822 +Licence type (autodetected): BSD-3-Clause +-------------------------------------------------------------------------------- -2.6. Fair Use +Contents of probable licence file $GOMODCACHE/github.com/munnerz/goautoneg@v0.0.0-20191010083416-a7dc8b61c822/LICENSE: - This License is not intended to limit any rights You have under - applicable copyright doctrines of fair use, fair dealing, or other - equivalents. +Copyright (c) 2011, Open Knowledge Foundation Ltd. +All rights reserved. -2.7. Conditions +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: - Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in - Section 2.1. + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. -3. Responsibilities + Neither the name of the Open Knowledge Foundation Ltd. nor the + names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. -3.1. Distribution of Source Form +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - All distribution of Covered Software in Source Code Form, including any - Modifications that You create or to which You contribute, must be under - the terms of this License. You must inform recipients that the Source - Code Form of the Covered Software is governed by the terms of this - License, and how they can obtain a copy of this License. You may not - attempt to alter or restrict the recipients' rights in the Source Code - Form. -3.2. Distribution of Executable Form +-------------------------------------------------------------------------------- +Dependency : github.com/pbnjay/memory +Version: v0.0.0-20210728143218-7b4eea64cf58 +Licence type (autodetected): BSD-3-Clause +-------------------------------------------------------------------------------- - If You distribute Covered Software in Executable Form then: +Contents of probable licence file $GOMODCACHE/github.com/pbnjay/memory@v0.0.0-20210728143218-7b4eea64cf58/LICENSE: - a. such Covered Software must also be made available in Source Code Form, - as described in Section 3.1, and You must inform recipients of the - Executable Form how they can obtain a copy of such Source Code Form by - reasonable means in a timely manner, at a charge no more than the cost - of distribution to the recipient; and +BSD 3-Clause License - b. You may distribute such Executable Form under the terms of this - License, or sublicense it under different terms, provided that the - license for the Executable Form does not attempt to limit or alter the - recipients' rights in the Source Code Form under this License. +Copyright (c) 2017, Jeremy Jay +All rights reserved. -3.3. Distribution of a Larger Work +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: - You may create and distribute a Larger Work under terms of Your choice, - provided that You also comply with the requirements of this License for - the Covered Software. If the Larger Work is a combination of Covered - Software with a work governed by one or more Secondary Licenses, and the - Covered Software is not Incompatible With Secondary Licenses, this - License permits You to additionally distribute such Covered Software - under the terms of such Secondary License(s), so that the recipient of - the Larger Work may, at their option, further distribute the Covered - Software under the terms of either this License or such Secondary - License(s). +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. -3.4. Notices +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. - You may not remove or alter the substance of any license notices - (including copyright notices, patent notices, disclaimers of warranty, or - limitations of liability) contained within the Source Code Form of the - Covered Software, except that You may alter any license notices to the - extent required to remedy known factual inaccuracies. +* Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. -3.5. Application of Additional Terms +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - You may choose to offer, and to charge a fee for, warranty, support, - indemnity or liability obligations to one or more recipients of Covered - Software. However, You may do so only on Your own behalf, and not on - behalf of any Contributor. You must make it absolutely clear that any - such warranty, support, indemnity, or liability obligation is offered by - You alone, and You hereby agree to indemnify every Contributor for any - liability incurred by such Contributor as a result of warranty, support, - indemnity or liability terms You offer. You may include additional - disclaimers of warranty and limitations of liability specific to any - jurisdiction. -4. Inability to Comply Due to Statute or Regulation +-------------------------------------------------------------------------------- +Dependency : github.com/pierrec/lz4/v4 +Version: v4.1.21 +Licence type (autodetected): BSD-3-Clause +-------------------------------------------------------------------------------- - If it is impossible for You to comply with any of the terms of this License - with respect to some or all of the Covered Software due to statute, - judicial order, or regulation then You must: (a) comply with the terms of - this License to the maximum extent possible; and (b) describe the - limitations and the code they affect. Such description must be placed in a - text file included with all distributions of the Covered Software under - this License. Except to the extent prohibited by statute or regulation, - such description must be sufficiently detailed for a recipient of ordinary - skill to be able to understand it. +Contents of probable licence file $GOMODCACHE/github.com/pierrec/lz4/v4@v4.1.21/LICENSE: -5. Termination +Copyright (c) 2015, Pierre Curto +All rights reserved. -5.1. The rights granted under this License will terminate automatically if You - fail to comply with any of its terms. However, if You become compliant, - then the rights granted under this License from a particular Contributor - are reinstated (a) provisionally, unless and until such Contributor - explicitly and finally terminates Your grants, and (b) on an ongoing - basis, if such Contributor fails to notify You of the non-compliance by - some reasonable means prior to 60 days after You have come back into - compliance. Moreover, Your grants from a particular Contributor are - reinstated on an ongoing basis if such Contributor notifies You of the - non-compliance by some reasonable means, this is the first time You have - received notice of non-compliance with this License from such - Contributor, and You become compliant prior to 30 days after Your receipt - of the notice. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: -5.2. If You initiate litigation against any entity by asserting a patent - infringement claim (excluding declaratory judgment actions, - counter-claims, and cross-claims) alleging that a Contributor Version - directly or indirectly infringes any patent, then the rights granted to - You by any and all Contributors for the Covered Software under Section - 2.1 of this License shall terminate. +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. -5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user - license agreements (excluding distributors and resellers) which have been - validly granted by You or Your distributors under this License prior to - termination shall survive termination. +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. -6. Disclaimer of Warranty +* Neither the name of xxHash nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. - Covered Software is provided under this License on an "as is" basis, - without warranty of any kind, either expressed, implied, or statutory, - including, without limitation, warranties that the Covered Software is free - of defects, merchantable, fit for a particular purpose or non-infringing. - The entire risk as to the quality and performance of the Covered Software - is with You. Should any Covered Software prove defective in any respect, - You (not any Contributor) assume the cost of any necessary servicing, - repair, or correction. This disclaimer of warranty constitutes an essential - part of this License. No use of any Covered Software is authorized under - this License except under this disclaimer. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -7. Limitation of Liability - Under no circumstances and under no legal theory, whether tort (including - negligence), contract, or otherwise, shall any Contributor, or anyone who - distributes Covered Software as permitted above, be liable to You for any - direct, indirect, special, incidental, or consequential damages of any - character including, without limitation, damages for lost profits, loss of - goodwill, work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses, even if such party shall have been - informed of the possibility of such damages. This limitation of liability - shall not apply to liability for death or personal injury resulting from - such party's negligence to the extent applicable law prohibits such - limitation. Some jurisdictions do not allow the exclusion or limitation of - incidental or consequential damages, so this exclusion and limitation may - not apply to You. -8. Litigation +-------------------------------------------------------------------------------- +Dependency : github.com/planetscale/vtprotobuf +Version: v0.6.1-0.20240319094008-0393e58bdf10 +Licence type (autodetected): BSD-3-Clause +-------------------------------------------------------------------------------- - Any litigation relating to this License may be brought only in the courts - of a jurisdiction where the defendant maintains its principal place of - business and such litigation shall be governed by laws of that - jurisdiction, without reference to its conflict-of-law provisions. Nothing - in this Section shall prevent a party's ability to bring cross-claims or - counter-claims. +Contents of probable licence file $GOMODCACHE/github.com/planetscale/vtprotobuf@v0.6.1-0.20240319094008-0393e58bdf10/LICENSE: -9. Miscellaneous +Copyright (c) 2021, PlanetScale Inc. All rights reserved. +Copyright (c) 2013, The GoGo Authors. All rights reserved. +Copyright (c) 2018 The Go Authors. All rights reserved. - This License represents the complete agreement concerning the subject - matter hereof. If any provision of this License is held to be - unenforceable, such provision shall be reformed only to the extent - necessary to make it enforceable. Any law or regulation which provides that - the language of a contract shall be construed against the drafter shall not - be used to construe this License against a Contributor. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. -10. Versions of the License +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -10.1. New Versions - Mozilla Foundation is the license steward. Except as provided in Section - 10.3, no one other than the license steward has the right to modify or - publish new versions of this License. Each version will be given a - distinguishing version number. +-------------------------------------------------------------------------------- +Dependency : github.com/pmezard/go-difflib +Version: v1.0.1-0.20181226105442-5d4384ee4fb2 +Licence type (autodetected): BSD-3-Clause +-------------------------------------------------------------------------------- -10.2. Effect of New Versions +Contents of probable licence file $GOMODCACHE/github.com/pmezard/go-difflib@v1.0.1-0.20181226105442-5d4384ee4fb2/LICENSE: - You may distribute the Covered Software under the terms of the version - of the License under which You originally received the Covered Software, - or under the terms of any subsequent version published by the license - steward. +Copyright (c) 2013, Patrick Mezard +All rights reserved. -10.3. Modified Versions +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: - If you create software not governed by this License, and you want to - create a new license for such software, you may create and use a - modified version of this License if you rename the license and remove - any references to the name of the license steward (except to note that - such modified license differs from this License). + Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. + The names of its contributors may not be used to endorse or promote +products derived from this software without specific prior written +permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED +TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -10.4. Distributing Source Code Form that is Incompatible With Secondary - Licenses If You choose to distribute Source Code Form that is - Incompatible With Secondary Licenses under the terms of this version of - the License, the notice described in Exhibit B of this License must be - attached. -Exhibit A - Source Code Form License Notice +-------------------------------------------------------------------------------- +Dependency : github.com/prometheus/client_golang +Version: v1.20.5 +Licence type (autodetected): Apache-2.0 +-------------------------------------------------------------------------------- - This Source Code Form is subject to the - terms of the Mozilla Public License, v. - 2.0. If a copy of the MPL was not - distributed with this file, You can - obtain one at - http://mozilla.org/MPL/2.0/. +Contents of probable licence file $GOMODCACHE/github.com/prometheus/client_golang@v1.20.5/LICENSE: -If it is not possible or desirable to put the notice in a particular file, -then You may include the notice in a location (such as a LICENSE file in a -relevant directory) where a recipient would be likely to look for such a -notice. + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ -You may add additional accurate notices of copyright ownership. + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION -Exhibit B - "Incompatible With Secondary Licenses" Notice + 1. Definitions. - This Source Code Form is "Incompatible - With Secondary Licenses", as defined by - the Mozilla Public License, v. 2.0. + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. -------------------------------------------------------------------------------- -Dependency : github.com/tklauser/go-sysconf -Version: v0.3.12 -Licence type (autodetected): BSD-3-Clause +Dependency : github.com/prometheus/client_model +Version: v0.6.1 +Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/github.com/tklauser/go-sysconf@v0.3.12/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/prometheus/client_model@v0.6.1/LICENSE: + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. -BSD 3-Clause License + END OF TERMS AND CONDITIONS -Copyright (c) 2018-2022, Tobias Klauser -All rights reserved. + APPENDIX: How to apply the Apache License to your work. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. -* Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. + Copyright [yyyy] [name of copyright owner] -* Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at -* Neither the name of the copyright holder nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. + http://www.apache.org/licenses/LICENSE-2.0 -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. -------------------------------------------------------------------------------- -Dependency : github.com/tklauser/numcpus -Version: v0.6.1 +Dependency : github.com/prometheus/common +Version: v0.60.1 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/github.com/tklauser/numcpus@v0.6.1/LICENSE: - +Contents of probable licence file $GOMODCACHE/github.com/prometheus/common@v0.60.1/LICENSE: Apache License Version 2.0, January 2004 @@ -15426,13 +14270,12 @@ Contents of probable licence file $GOMODCACHE/github.com/tklauser/numcpus@v0.6.1 -------------------------------------------------------------------------------- -Dependency : github.com/xdg-go/pbkdf2 -Version: v1.0.0 +Dependency : github.com/prometheus/procfs +Version: v0.15.1 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/github.com/xdg-go/pbkdf2@v1.0.0/LICENSE: - +Contents of probable licence file $GOMODCACHE/github.com/prometheus/procfs@v0.15.1/LICENSE: Apache License Version 2.0, January 2004 @@ -15609,199 +14452,226 @@ Contents of probable licence file $GOMODCACHE/github.com/xdg-go/pbkdf2@v1.0.0/LI incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + -------------------------------------------------------------------------------- -Dependency : github.com/xdg-go/scram -Version: v1.1.2 -Licence type (autodetected): Apache-2.0 +Dependency : github.com/rcrowley/go-metrics +Version: v0.0.0-20201227073835-cf1acfcdf475 +Licence type (autodetected): BSD-2-Clause-FreeBSD -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/github.com/xdg-go/scram@v1.1.2/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/rcrowley/go-metrics@v0.0.0-20201227073835-cf1acfcdf475/LICENSE: +Copyright 2012 Richard Crowley. All rights reserved. - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. - 1. Definitions. + 2. Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. +THIS SOFTWARE IS PROVIDED BY RICHARD CROWLEY ``AS IS'' AND ANY EXPRESS +OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL RICHARD CROWLEY OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +THE POSSIBILITY OF SUCH DAMAGE. - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. +The views and conclusions contained in the software and documentation +are those of the authors and should not be interpreted as representing +official policies, either expressed or implied, of Richard Crowley. - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. +-------------------------------------------------------------------------------- +Dependency : github.com/rogpeppe/go-internal +Version: v1.13.1 +Licence type (autodetected): BSD-3-Clause +-------------------------------------------------------------------------------- - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. +Contents of probable licence file $GOMODCACHE/github.com/rogpeppe/go-internal@v1.13.1/LICENSE: - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. +Copyright (c) 2018 The Go Authors. All rights reserved. - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. +-------------------------------------------------------------------------------- +Dependency : github.com/shirou/gopsutil/v4 +Version: v4.24.9 +Licence type (autodetected): BSD-3-Clause +-------------------------------------------------------------------------------- + +Contents of probable licence file $GOMODCACHE/github.com/shirou/gopsutil/v4@v4.24.9/LICENSE: + +gopsutil is distributed under BSD license reproduced below. + +Copyright (c) 2014, WAKAYAMA Shirou +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of the gopsutil authors nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +------- +internal/common/binary.go in the gopsutil is copied and modified from golang/encoding/binary.go. + - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: +Copyright (c) 2009 The Go Authors. All rights reserved. - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. +-------------------------------------------------------------------------------- +Dependency : github.com/tklauser/go-sysconf +Version: v0.3.12 +Licence type (autodetected): BSD-3-Clause +-------------------------------------------------------------------------------- - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. +Contents of probable licence file $GOMODCACHE/github.com/tklauser/go-sysconf@v0.3.12/LICENSE: - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. +BSD 3-Clause License - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. +Copyright (c) 2018-2022, Tobias Klauser +All rights reserved. - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- -Dependency : github.com/xdg-go/stringprep -Version: v1.0.4 +Dependency : github.com/tklauser/numcpus +Version: v0.6.1 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/github.com/xdg-go/stringprep@v1.0.4/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/tklauser/numcpus@v0.6.1/LICENSE: Apache License @@ -15979,44 +14849,42 @@ Contents of probable licence file $GOMODCACHE/github.com/xdg-go/stringprep@v1.0. incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. + END OF TERMS AND CONDITIONS --------------------------------------------------------------------------------- -Dependency : github.com/yusufpapurcu/wmi -Version: v1.2.4 -Licence type (autodetected): MIT --------------------------------------------------------------------------------- - -Contents of probable licence file $GOMODCACHE/github.com/yusufpapurcu/wmi@v1.2.4/LICENSE: + APPENDIX: How to apply the Apache License to your work. -The MIT License (MIT) + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. -Copyright (c) 2013 Stack Exchange + Copyright [yyyy] [name of copyright owner] -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. + http://www.apache.org/licenses/LICENSE-2.0 -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. -------------------------------------------------------------------------------- -Dependency : go.elastic.co/apm/module/apmzap/v2 -Version: v2.6.0 +Dependency : github.com/xdg-go/pbkdf2 +Version: v1.0.0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/go.elastic.co/apm/module/apmzap/v2@v2.6.0/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/xdg-go/pbkdf2@v1.0.0/LICENSE: + Apache License Version 2.0, January 2004 @@ -16193,41 +15061,14 @@ Contents of probable licence file $GOMODCACHE/go.elastic.co/apm/module/apmzap/v2 incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2018 Elasticsearch BV - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - -------------------------------------------------------------------------------- -Dependency : go.elastic.co/ecszap -Version: v1.0.2 +Dependency : github.com/xdg-go/scram +Version: v1.1.2 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/go.elastic.co/ecszap@v1.0.2/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/xdg-go/scram@v1.1.2/LICENSE: Apache License @@ -16385,60 +15226,34 @@ Contents of probable licence file $GOMODCACHE/go.elastic.co/ecszap@v1.0.2/LICENS 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2020 Elastic and contributors - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. - http://www.apache.org/licenses/LICENSE-2.0 + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -------------------------------------------------------------------------------- -Dependency : go.opentelemetry.io/collector/semconv -Version: v0.109.0 +Dependency : github.com/xdg-go/stringprep +Version: v1.0.4 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/collector/semconv@v0.109.0/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/xdg-go/stringprep@v1.0.4/LICENSE: Apache License @@ -16616,41 +15431,44 @@ Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/collector/semc incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. - END OF TERMS AND CONDITIONS - APPENDIX: How to apply the Apache License to your work. +-------------------------------------------------------------------------------- +Dependency : github.com/yusufpapurcu/wmi +Version: v1.2.4 +Licence type (autodetected): MIT +-------------------------------------------------------------------------------- - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. +Contents of probable licence file $GOMODCACHE/github.com/yusufpapurcu/wmi@v1.2.4/LICENSE: - Copyright [yyyy] [name of copyright owner] +The MIT License (MIT) - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at +Copyright (c) 2013 Stack Exchange - http://www.apache.org/licenses/LICENSE-2.0 +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- -Dependency : go.opentelemetry.io/otel/sdk -Version: v1.30.0 +Dependency : go.elastic.co/apm/module/apmzap/v2 +Version: v2.6.3 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/otel/sdk@v1.30.0/LICENSE: +Contents of probable licence file $GOMODCACHE/go.elastic.co/apm/module/apmzap/v2@v2.6.3/LICENSE: Apache License Version 2.0, January 2004 @@ -16840,7 +15658,7 @@ Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/otel/sdk@v1.30 same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright [yyyy] [name of copyright owner] + Copyright 2018 Elasticsearch BV Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -16856,12 +15674,13 @@ Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/otel/sdk@v1.30 -------------------------------------------------------------------------------- -Dependency : go.opentelemetry.io/otel/trace -Version: v1.30.0 +Dependency : go.elastic.co/ecszap +Version: v1.0.2 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/otel/trace@v1.30.0/LICENSE: +Contents of probable licence file $GOMODCACHE/go.elastic.co/ecszap@v1.0.2/LICENSE: + Apache License Version 2.0, January 2004 @@ -17023,234 +15842,55 @@ Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/otel/trace@v1. incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - --------------------------------------------------------------------------------- -Dependency : go.uber.org/multierr -Version: v1.11.0 -Licence type (autodetected): MIT --------------------------------------------------------------------------------- - -Contents of probable licence file $GOMODCACHE/go.uber.org/multierr@v1.11.0/LICENSE.txt: - -Copyright (c) 2017-2021 Uber Technologies, Inc. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - - --------------------------------------------------------------------------------- -Dependency : golang.org/x/crypto -Version: v0.28.0 -Licence type (autodetected): BSD-3-Clause --------------------------------------------------------------------------------- - -Contents of probable licence file $GOMODCACHE/golang.org/x/crypto@v0.28.0/LICENSE: - -Copyright 2009 The Go Authors. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google LLC nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - --------------------------------------------------------------------------------- -Dependency : golang.org/x/exp -Version: v0.0.0-20240506185415-9bf2ced13842 -Licence type (autodetected): BSD-3-Clause --------------------------------------------------------------------------------- - -Contents of probable licence file $GOMODCACHE/golang.org/x/exp@v0.0.0-20240506185415-9bf2ced13842/LICENSE: - -Copyright (c) 2009 The Go Authors. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - --------------------------------------------------------------------------------- -Dependency : golang.org/x/sys -Version: v0.26.0 -Licence type (autodetected): BSD-3-Clause --------------------------------------------------------------------------------- - -Contents of probable licence file $GOMODCACHE/golang.org/x/sys@v0.26.0/LICENSE: - -Copyright 2009 The Go Authors. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google LLC nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. --------------------------------------------------------------------------------- -Dependency : golang.org/x/text -Version: v0.19.0 -Licence type (autodetected): BSD-3-Clause --------------------------------------------------------------------------------- + END OF TERMS AND CONDITIONS -Contents of probable licence file $GOMODCACHE/golang.org/x/text@v0.19.0/LICENSE: + APPENDIX: How to apply the Apache License to your work. -Copyright 2009 The Go Authors. + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: + Copyright 2020 Elastic and contributors - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google LLC nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. -------------------------------------------------------------------------------- -Dependency : google.golang.org/genproto/googleapis/rpc -Version: v0.0.0-20240822170219-fc7c04adadcd +Dependency : go.opentelemetry.io/auto/sdk +Version: v1.1.0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/google.golang.org/genproto/googleapis/rpc@v0.0.0-20240822170219-fc7c04adadcd/LICENSE: - +Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/auto/sdk@v1.1.0/LICENSE: Apache License Version 2.0, January 2004 @@ -17456,12 +16096,13 @@ Contents of probable licence file $GOMODCACHE/google.golang.org/genproto/googlea -------------------------------------------------------------------------------- -Dependency : gopkg.in/jcmturner/aescts.v1 -Version: v1.0.1 +Dependency : go.opentelemetry.io/collector/consumer +Version: v1.22.0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/gopkg.in/jcmturner/aescts.v1@v1.0.1/LICENSE: +Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/collector/consumer@v1.22.0/LICENSE: + Apache License Version 2.0, January 2004 @@ -17643,7 +16284,7 @@ Contents of probable licence file $GOMODCACHE/gopkg.in/jcmturner/aescts.v1@v1.0. APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" + boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a @@ -17651,7 +16292,7 @@ Contents of probable licence file $GOMODCACHE/gopkg.in/jcmturner/aescts.v1@v1.0. same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright {yyyy} {name of copyright owner} + Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -17667,12 +16308,13 @@ Contents of probable licence file $GOMODCACHE/gopkg.in/jcmturner/aescts.v1@v1.0. -------------------------------------------------------------------------------- -Dependency : gopkg.in/jcmturner/dnsutils.v1 -Version: v1.0.1 +Dependency : go.opentelemetry.io/collector/semconv +Version: v0.116.0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/gopkg.in/jcmturner/dnsutils.v1@v1.0.1/LICENSE: +Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/collector/semconv@v0.116.0/LICENSE: + Apache License Version 2.0, January 2004 @@ -17878,12 +16520,12 @@ Contents of probable licence file $GOMODCACHE/gopkg.in/jcmturner/dnsutils.v1@v1. -------------------------------------------------------------------------------- -Dependency : gopkg.in/jcmturner/goidentity.v3 -Version: v3.0.0 +Dependency : go.opentelemetry.io/otel/sdk +Version: v1.34.0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/gopkg.in/jcmturner/goidentity.v3@v3.0.0/LICENSE: +Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/otel/sdk@v1.34.0/LICENSE: Apache License Version 2.0, January 2004 @@ -18065,7 +16707,7 @@ Contents of probable licence file $GOMODCACHE/gopkg.in/jcmturner/goidentity.v3@v APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" + boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a @@ -18073,7 +16715,7 @@ Contents of probable licence file $GOMODCACHE/gopkg.in/jcmturner/goidentity.v3@v same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright {yyyy} {name of copyright owner} + Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -18089,12 +16731,12 @@ Contents of probable licence file $GOMODCACHE/gopkg.in/jcmturner/goidentity.v3@v -------------------------------------------------------------------------------- -Dependency : gopkg.in/jcmturner/gokrb5.v7 -Version: v7.5.0 +Dependency : go.opentelemetry.io/otel/trace +Version: v1.34.0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/gopkg.in/jcmturner/gokrb5.v7@v7.5.0/LICENSE: +Contents of probable licence file $GOMODCACHE/go.opentelemetry.io/otel/trace@v1.34.0/LICENSE: Apache License Version 2.0, January 2004 @@ -18276,7 +16918,7 @@ Contents of probable licence file $GOMODCACHE/gopkg.in/jcmturner/gokrb5.v7@v7.5. APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" + boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a @@ -18284,7 +16926,7 @@ Contents of probable licence file $GOMODCACHE/gopkg.in/jcmturner/gokrb5.v7@v7.5. same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright {yyyy} {name of copyright owner} + Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -18300,12 +16942,190 @@ Contents of probable licence file $GOMODCACHE/gopkg.in/jcmturner/gokrb5.v7@v7.5. -------------------------------------------------------------------------------- -Dependency : gopkg.in/jcmturner/rpc.v1 -Version: v1.1.0 +Dependency : go.uber.org/multierr +Version: v1.11.0 +Licence type (autodetected): MIT +-------------------------------------------------------------------------------- + +Contents of probable licence file $GOMODCACHE/go.uber.org/multierr@v1.11.0/LICENSE.txt: + +Copyright (c) 2017-2021 Uber Technologies, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + +-------------------------------------------------------------------------------- +Dependency : golang.org/x/crypto +Version: v0.32.0 +Licence type (autodetected): BSD-3-Clause +-------------------------------------------------------------------------------- + +Contents of probable licence file $GOMODCACHE/golang.org/x/crypto@v0.32.0/LICENSE: + +Copyright 2009 The Go Authors. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google LLC nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +-------------------------------------------------------------------------------- +Dependency : golang.org/x/exp +Version: v0.0.0-20241009180824-f66d83c29e7c +Licence type (autodetected): BSD-3-Clause +-------------------------------------------------------------------------------- + +Contents of probable licence file $GOMODCACHE/golang.org/x/exp@v0.0.0-20241009180824-f66d83c29e7c/LICENSE: + +Copyright 2009 The Go Authors. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google LLC nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +-------------------------------------------------------------------------------- +Dependency : golang.org/x/sys +Version: v0.29.0 +Licence type (autodetected): BSD-3-Clause +-------------------------------------------------------------------------------- + +Contents of probable licence file $GOMODCACHE/golang.org/x/sys@v0.29.0/LICENSE: + +Copyright 2009 The Go Authors. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google LLC nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +-------------------------------------------------------------------------------- +Dependency : golang.org/x/text +Version: v0.21.0 +Licence type (autodetected): BSD-3-Clause +-------------------------------------------------------------------------------- + +Contents of probable licence file $GOMODCACHE/golang.org/x/text@v0.21.0/LICENSE: + +Copyright 2009 The Go Authors. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google LLC nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +-------------------------------------------------------------------------------- +Dependency : google.golang.org/genproto/googleapis/rpc +Version: v0.0.0-20241209162323-e6fa225c2576 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/gopkg.in/jcmturner/rpc.v1@v1.1.0/LICENSE: +Contents of probable licence file $GOMODCACHE/google.golang.org/genproto/googleapis/rpc@v0.0.0-20241209162323-e6fa225c2576/LICENSE: + Apache License Version 2.0, January 2004 diff --git a/apm-server.docker.yml b/apm-server.docker.yml index f5fba96ea9d..8faac23b5b4 100644 --- a/apm-server.docker.yml +++ b/apm-server.docker.yml @@ -112,8 +112,8 @@ apm-server: # It is recommended to use the provided keystore instead of entering the passphrase in plain text. #key_passphrase: '' - # List of supported/valid protocol versions. By default TLS versions 1.1 up to 1.3 are enabled. - #supported_protocols: [TLSv1.1, TLSv1.2, TLSv1.3] + # List of supported/valid protocol versions. By default TLS versions 1.2 up to 1.3 are enabled. + #supported_protocols: [TLSv1.2, TLSv1.3] # Configure cipher suites to be used for SSL connections. # Note that cipher suites are not configurable for TLS 1.3. @@ -261,9 +261,9 @@ apm-server: # production environments is strongly discouraged. #ssl.verification_mode: full - # List of supported/valid TLS versions. By default all TLS versions 1.0 up to - # 1.2 are enabled. - #ssl.supported_protocols: [TLSv1.0, TLSv1.1, TLSv1.2] + # List of supported/valid TLS versions. By default all TLS versions 1.2 up to + # 1.3 are enabled. + #ssl.supported_protocols: [TLSv1.2, TLSv1.3] # List of root certificates for HTTPS server verifications. #ssl.certificate_authorities: ["/etc/pki/root/ca.pem"] @@ -397,9 +397,9 @@ output.elasticsearch: # production environments is strongly discouraged. #ssl.verification_mode: full - # List of supported/valid TLS versions. By default all TLS versions 1.0 up to - # 1.2 are enabled. - #ssl.supported_protocols: [TLSv1.0, TLSv1.1, TLSv1.2] + # List of supported/valid TLS versions. By default all TLS versions 1.2 up to + # 1.3 are enabled. + #ssl.supported_protocols: [TLSv1.2, TLSv1.3] # List of root certificates for HTTPS server verifications. #ssl.certificate_authorities: ["/etc/pki/root/ca.pem"] @@ -517,9 +517,9 @@ output.elasticsearch: # production environments is strongly discouraged. #ssl.verification_mode: full - # List of supported/valid TLS versions. By default all TLS versions 1.0 up to - # 1.2 are enabled. - #ssl.supported_protocols: [TLSv1.0, TLSv1.1, TLSv1.2] + # List of supported/valid TLS versions. By default all TLS versions 1.2 up to + # 1.3 are enabled. + #ssl.supported_protocols: [TLSv1.2, TLSv1.3] # List of root certificates for HTTPS server verifications. #ssl.certificate_authorities: ["/etc/pki/root/ca.pem"] @@ -676,9 +676,9 @@ output.elasticsearch: # production environments is strongly discouraged. #ssl.verification_mode: full - # List of supported/valid TLS versions. By default all TLS versions 1.0 up to - # 1.2 are enabled. - #ssl.supported_protocols: [TLSv1.0, TLSv1.1, TLSv1.2] + # List of supported/valid TLS versions. By default all TLS versions 1.2 up to + # 1.3 are enabled. + #ssl.supported_protocols: [TLSv1.2, TLSv1.3] # List of root certificates for HTTPS server verifications. #ssl.certificate_authorities: ["/etc/pki/root/ca.pem"] @@ -924,9 +924,9 @@ output.elasticsearch: # production environments is strongly discouraged. #ssl.verification_mode: full - # List of supported/valid TLS versions. By default all TLS versions 1.0 up to - # 1.2 are enabled. - #ssl.supported_protocols: [TLSv1.0, TLSv1.1, TLSv1.2] + # List of supported/valid TLS versions. By default all TLS versions 1.2 up to + # 1.3 are enabled. + #ssl.supported_protocols: [TLSv1.2, TLSv1.3] # List of root certificates for HTTPS server verifications. #ssl.certificate_authorities: ["/etc/pki/root/ca.pem"] diff --git a/apm-server.yml b/apm-server.yml index 35800aafd13..184426c878d 100644 --- a/apm-server.yml +++ b/apm-server.yml @@ -112,8 +112,8 @@ apm-server: # It is recommended to use the provided keystore instead of entering the passphrase in plain text. #key_passphrase: '' - # List of supported/valid protocol versions. By default TLS versions 1.1 up to 1.3 are enabled. - #supported_protocols: [TLSv1.1, TLSv1.2, TLSv1.3] + # List of supported/valid protocol versions. By default TLS versions 1.2 up to 1.3 are enabled. + #supported_protocols: [TLSv1.2, TLSv1.3] # Configure cipher suites to be used for SSL connections. # Note that cipher suites are not configurable for TLS 1.3. @@ -261,9 +261,9 @@ apm-server: # production environments is strongly discouraged. #ssl.verification_mode: full - # List of supported/valid TLS versions. By default all TLS versions 1.0 up to - # 1.2 are enabled. - #ssl.supported_protocols: [TLSv1.0, TLSv1.1, TLSv1.2] + # List of supported/valid TLS versions. By default all TLS versions 1.2 up to + # 1.3 are enabled. + #ssl.supported_protocols: [TLSv1.2, TLSv1.3] # List of root certificates for HTTPS server verifications. #ssl.certificate_authorities: ["/etc/pki/root/ca.pem"] @@ -397,9 +397,9 @@ output.elasticsearch: # production environments is strongly discouraged. #ssl.verification_mode: full - # List of supported/valid TLS versions. By default all TLS versions 1.0 up to - # 1.2 are enabled. - #ssl.supported_protocols: [TLSv1.0, TLSv1.1, TLSv1.2] + # List of supported/valid TLS versions. By default all TLS versions 1.2 up to + # 1.3 are enabled. + #ssl.supported_protocols: [TLSv1.2, TLSv1.3] # List of root certificates for HTTPS server verifications. #ssl.certificate_authorities: ["/etc/pki/root/ca.pem"] @@ -517,9 +517,9 @@ output.elasticsearch: # production environments is strongly discouraged. #ssl.verification_mode: full - # List of supported/valid TLS versions. By default all TLS versions 1.0 up to - # 1.2 are enabled. - #ssl.supported_protocols: [TLSv1.0, TLSv1.1, TLSv1.2] + # List of supported/valid TLS versions. By default all TLS versions 1.2 up to + # 1.3 are enabled. + #ssl.supported_protocols: [TLSv1.2, TLSv1.3] # List of root certificates for HTTPS server verifications. #ssl.certificate_authorities: ["/etc/pki/root/ca.pem"] @@ -676,9 +676,9 @@ output.elasticsearch: # production environments is strongly discouraged. #ssl.verification_mode: full - # List of supported/valid TLS versions. By default all TLS versions 1.0 up to - # 1.2 are enabled. - #ssl.supported_protocols: [TLSv1.0, TLSv1.1, TLSv1.2] + # List of supported/valid TLS versions. By default all TLS versions 1.2 up to + # 1.3 are enabled. + #ssl.supported_protocols: [TLSv1.2, TLSv1.3] # List of root certificates for HTTPS server verifications. #ssl.certificate_authorities: ["/etc/pki/root/ca.pem"] @@ -924,9 +924,9 @@ output.elasticsearch: # production environments is strongly discouraged. #ssl.verification_mode: full - # List of supported/valid TLS versions. By default all TLS versions 1.0 up to - # 1.2 are enabled. - #ssl.supported_protocols: [TLSv1.0, TLSv1.1, TLSv1.2] + # List of supported/valid TLS versions. By default all TLS versions 1.2 up to + # 1.3 are enabled. + #ssl.supported_protocols: [TLSv1.2, TLSv1.3] # List of root certificates for HTTPS server verifications. #ssl.certificate_authorities: ["/etc/pki/root/ca.pem"] diff --git a/changelogs/8.15.asciidoc b/changelogs/8.15.asciidoc index 2623162ef76..e805f6f7d32 100644 --- a/changelogs/8.15.asciidoc +++ b/changelogs/8.15.asciidoc @@ -1,20 +1,42 @@ [[apm-release-notes-8.15]] == APM version 8.15 +* <> +* <> +* <> * <> * <> * <> [float] -[[apm-release-notes-8.15.2]] -=== APM version 8.15.2 +[[apm-release-notes-8.15.5]] +=== APM version 8.15.5 -https://github.com/elastic/apm-server/compare/v8.15.1\...v8.15.2[View commits] +https://github.com/elastic/apm-server/compare/v8.15.4\...v8.15.5[View commits] + +No significant changes. + +[float] +[[apm-release-notes-8.15.4]] +=== APM version 8.15.4 + +https://github.com/elastic/apm-server/compare/v8.15.3\...v8.15.4[View commits] + +[float] +==== Bug fixes + +- Rollover for all APM data streams is now executing correctly in Elasticsearch 8.15.4, fixing a https://www.elastic.co/guide/en/observability/current/apm-known-issues.html#_upgrading_to_v8_15_x_may_cause_ingestion_to_fail[known issue] present in 8.15.0, 8.15.1, 8.15.2 and 8.15.3. + The fix is applied through https://github.com/elastic/elasticsearch/pull/116219[elasticsearch#116219]. + +[float] +[[apm-release-notes-8.15.3]] +=== APM version 8.15.3 + +https://github.com/elastic/apm-server/compare/v8.15.2\...v8.15.3[View commits] [float] ==== Bug fixes -- Fix broken APM Agents configuration cache when there are more than 100 agent config entries {pull}13958[13958] - Fix a panic in OTLP label setting when receiving on non-compliant attribute array values {pull}13950[13950] [float] @@ -22,6 +44,17 @@ https://github.com/elastic/apm-server/compare/v8.15.1\...v8.15.2[View commits] - Map OpenTelemetry instrumentation scope to `Service.Framework.*` for all signal types. {pull}13903[13903] +[float] +[[apm-release-notes-8.15.2]] +=== APM version 8.15.2 + +https://github.com/elastic/apm-server/compare/v8.15.1\...v8.15.2[View commits] + +[float] +==== Bug fixes + +- Fix broken APM Agents configuration cache when there are more than 100 agent config entries {pull}13958[13958] + [float] [[apm-release-notes-8.15.1]] === APM version 8.15.1 @@ -68,9 +101,10 @@ https://github.com/elastic/apm-server/compare/v8.14.3\...v8.15.0[View commits] - Add `elasticsearch.flushed.uncompressed.bytes` metric {pull}13155[13155] - APM Server now relies on the Elasticsearch apm-data plugin's index templates, removing the requirement to install the APM integration package {pull}12066[12066] +- Switch the default lifecycle management to leverage DSL instead of ILM, the change is executed as a part of Elasticsearch apm-data plugin migration {pull}12066[12066] - Upgraded bundled APM Java agent attacher CLI to version 1.50.0 {pull}13326[13326] - Enable Kibana curated UIs to work with hostmetrics from OpenTelemetry's https://pkg.go.dev/go.opentelemetry.io/collector/receiver/hostmetricsreceiver[hostmetricsreceiver] {pull}13196[13196] - Add require data stream to bulk index requests {pull}13398[13398] - Support self-instrumentation when in managed mode by getting tracing configs via reloader {pull}13514[13514] {pull}13653[13653] {pull}13691[13691] {pull}13790[13790] - Add mapping for OpenTelemetry attribute `messaging.destination.name` to derive `service.target` correctly {pull}13472[13472] -- APM Server now automatically retries document-level 429s from Elasticsearch to avoid dropping data. `output.elasticsearch.max_retries` now controls both request-level and document-level retries, and defaults to `3`. {pull}13620[13620] +- APM Server now automatically retries document-level 429s from Elasticsearch to avoid dropping data. `output.elasticsearch.max_retries` now controls both request-level and document-level retries, and defaults to `3`. {pull}13620[13620] \ No newline at end of file diff --git a/changelogs/8.16.asciidoc b/changelogs/8.16.asciidoc new file mode 100644 index 00000000000..aa28226457f --- /dev/null +++ b/changelogs/8.16.asciidoc @@ -0,0 +1,111 @@ +[[apm-release-notes-8.16]] +== APM version 8.16 + +* <> +* <> +* <> +* <> + +[float] +[[apm-release-notes-8.16.3]] +=== APM version 8.16.3 + +https://github.com/elastic/apm-server/compare/v8.16.2\...v8.16.3[View commits] + +[float] +==== Bug fixes + +- Install APM Server in Program Files directory on Windows {pull}14905[14905] +- Fix self instrumentation events inconsistency when dealing with request timeout {pull}15123[15123] +- Drop and recreate tail-based sampling badger db after exceeding storage limit for configured TTL time {pull}15106[15106] + +[float] +==== Breaking Changes + +[float] +==== Deprecations + +[float] +==== Intake API Changes + +[float] +==== Added + +- Add sampling.tail.discard_on_write_failure config (default=false) to opt in to data loss when tail-based sampling storage limit is reached {pull}15159[15159] + +[float] +[[apm-release-notes-8.16.2]] +=== APM version 8.16.2 + +https://github.com/elastic/apm-server/compare/v8.16.1\...v8.16.2[View commits] + +[float] +==== Bug fixes + +- Surface config parsing error under EA managed mode by logging and marking EA input unit as failed {pull}14574[14574] +- Remove unnecessary hot reload under EA managed mode when apm tracing config is nil {pull}14865[14865] + +[float] +==== Breaking Changes + +[float] +==== Deprecations + +[float] +==== Intake API Changes + +[float] +==== Added + +- In this release we've introduced an image based on the hardened https://wolfi.dev/[Wolfi] image to provide additional security to our self-managed customers, and improve our supply chain security posture. + +[float] +[[apm-release-notes-8.16.1]] +=== APM version 8.16.1 + +https://github.com/elastic/apm-server/compare/v8.16.0\...v8.16.1[View commits] + +[float] +==== Bug fixes + +[float] +==== Breaking Changes + +[float] +==== Deprecations + +[float] +==== Intake API Changes + +[float] +==== Added + +[float] +[[apm-release-notes-8.16.0]] +=== APM version 8.16.0 + +https://github.com/elastic/apm-server/compare/v8.15.2\...v8.16.0[View commits] + +[float] +==== Bug fixes + +- Track all bulk request response status codes {pull}13574[13574] +- Fix a concurrent map write panic in monitoring middleware {pull}14335[14335] +- Apply shutdown timeout to http server {pull}14339[14339] +- Tail-based sampling: Fix rare gc thread failure after EA hot reload causing storage not reclaimed and stuck with "storage limit reached" {pull}14340[14340] + +[float] +==== Breaking Changes + +[float] +==== Deprecations +- Support for Jaeger is now deprecated, and will be removed in a future release {pull}13809[13809] + +[float] +==== Intake API Changes + +[float] +==== Added + +- APM Server will no longer retry an HTTP request that returned 502s, 503s, 504s. It will only retry 429s. {pull}13523[13523] +- APM Server now supports emitting distributed tracing for its own operation when running under Elastic Agent, and adds support for configuring a sampling rate {pull}14231[14231] diff --git a/changelogs/8.17.asciidoc b/changelogs/8.17.asciidoc new file mode 100644 index 00000000000..d87eaa6e703 --- /dev/null +++ b/changelogs/8.17.asciidoc @@ -0,0 +1,64 @@ +[[apm-release-notes-8.17]] +== APM version 8.17 + +* <> +* <> + +[float] +[[apm-release-notes-8.17.1]] +=== APM version 8.17.1 + +https://github.com/elastic/apm-server/compare/v8.17.0\...v8.17.1[View commits] + +[float] +==== Bug fixes + +- Install APM Server in Program Files directory on Windows {pull}14905[14905] +- Fix self instrumentation events inconsistency when dealing with request timeout {pull}15123[15123] +- Drop and recreate tail-based sampling badger db after exceeding storage limit for configured TTL time {pull}15106[15106] + +[float] +==== Breaking Changes + +[float] +==== Deprecations + +[float] +==== Intake API Changes + +[float] +==== Added + +- Add sampling.tail.discard_on_write_failure config (default=false) to opt in to data loss when tail-based sampling storage limit is reached {pull}15159[15159] + +[float] +[[apm-release-notes-8.17.0]] +=== APM version 8.17.0 + +https://github.com/elastic/apm-server/compare/v8.16.0\...v8.17.0[View commits] + +[float] +==== Bug fixes + +- Clear scroll after completing scroll requests {pull}14551[14551] +- Surface config parsing error under EA managed mode by logging and marking EA input unit as failed {pull}14574[14574] +- Remove unnecessary hot reload under EA managed mode when apm tracing config is nil {pull}14865[14865] +- The mappings are updated to disable date_detection for all APM data streams. + The change is applied through https://github.com/elastic/elasticsearch/pull/116995[elasticsearch#116995] + +[float] +==== Breaking Changes + +[float] +==== Deprecations + +[float] +==== Intake API Changes + +[float] +==== Added + +- The default data lifecycle management mechanism is getting reverted from Data Stream Lifecycle (DSL) to Index Lifecycle Management (ILM), as originally used prior to the introduction of the APM data plugin in release 8.15.0. + No action is required from users for this change. + However, any custom DSL settings will not be preserved during the migration. + The change is applied through https://github.com/elastic/elasticsearch/pull/115687[elasticsearch#115687] \ No newline at end of file diff --git a/changelogs/head.asciidoc b/changelogs/head.asciidoc index ab1a5e60bcd..46aa533582f 100644 --- a/changelogs/head.asciidoc +++ b/changelogs/head.asciidoc @@ -1,24 +1,21 @@ [[release-notes-head]] == APM version HEAD -https://github.com/elastic/apm-server/compare/8.15\...main[View commits] +https://github.com/elastic/apm-server/compare/8.16\...8.x[View commits] [float] ==== Bug fixes - -- Track all bulk request response status codes {pull}13574[13574] +- Fix overflow in validation of `apm-server.agent.config.cache.expiration` on 32-bit architectures {pull}15216[15216] [float] ==== Breaking Changes [float] ==== Deprecations -- Support for Jaeger is now deprecated, and will be removed in a future release {pull}13809[13809] [float] ==== Intake API Changes [float] ==== Added - -- APM Server will no longer retry an HTTP request that returned 502s, 503s, 504s. It will only retry 429s. {pull}13523[13523] +- Tail-based sampling: Storage layer is rewritten to use Pebble database instead of BadgerDB. The new implementation offers a substantial throughput increase while consuming significantly less memory. Disk usage is lower and more stable. See PR for benchmark details. {pull}15235[15235] diff --git a/cmd/apm-server/main.go b/cmd/apm-server/main.go index 72244c3d3d3..e798ce017da 100644 --- a/cmd/apm-server/main.go +++ b/cmd/apm-server/main.go @@ -30,6 +30,9 @@ func main() { return beater.NewRunner(beater.RunnerParams{ Config: args.Config, Logger: args.Logger, + + MeterProvider: args.MeterProvider, + MetricsGatherer: args.MetricsGatherer, }) }, }) diff --git a/dev_docs/RELEASES.md b/dev_docs/RELEASES.md index fb1aebc2089..049aab07b93 100644 --- a/dev_docs/RELEASES.md +++ b/dev_docs/RELEASES.md @@ -17,15 +17,19 @@ For patch releases, only the version on the existing major and minor version bra * Trigger release workflow manually * For **patch releases**: run the [`run-patch-release`](https://github.com/elastic/apm-server/actions/workflows/run-patch-release.yml) workflow (In "Use workflow from", select `main` branch. Then in "The version", specify the **upcoming** patch release version - es: on `8.14.2` feature freeze you will use `8.14.2`). - This workflow will: create the release branch; update version across codebase; commit and create PR targeting the release branch. - Release notes for patch releases **must be manually added** (PR should target `main` branch and backported to the release branch): + This workflow will: create the `update-` branch, update version constants across the codebase and create a PR targeting the release branch. + Release notes for patch releases **must be manually added** at least one day before release. + Create a PR targeting the `main` branch and add the backport label for the release branch. + To add release notes: * Add a new section to the existing release notes file ([Sample PR](https://github.com/elastic/apm-server/pull/12680)). * Review the [changelogs/head](https://github.com/elastic/apm-server/tree/main/changelogs/head.asciidoc) file and move relevant changelog entries from `head.asciidoc` to `release_version.asciidoc` if the change is backported to release_version. If changes do not apply to the version being released, keep them in the `head.asciidoc` file. * Review the commits in the release to ensure all changes are reflected in the release notes. Check for backported changes without release notes in `release_version.asciidoc`. - * Add your PR to the documentation release issue ([Sample Issue](https://github.com/elastic/dev/issues/2485)). - * The PR should only be merged on release day. - * For **minor releases**: run the [`run-minor-release`](https://github.com/elastic/apm-server/actions/workflows/run-minor-release.yml) workflow (In "Use workflow from", select `main` branch. Then in "The version", specify the minor release version the release is for). - This workflow will: create the release branch; update the changelog for the release branch and open a PR targeting the release branch titled `.: update docs`; create a PR on `main` titled `.: update docs, mergify, versions and changelogs`. Before merging them compare commits between latest minor and the new minor versions and ensure all relevant PRs have been included in the Changelog. If not, amend it in both PRs. Request and wait a PR review from the team before merging. + * Add your PR to the documentation release issue in the [`elastic/dev`](https://github.com/elastic/dev/issues?q=is%3Aissue%20state%3Aopen%20label%3Adocs) repo ([Sample Issue](https://github.com/elastic/dev/issues/2485)). + * The PR should be merged the day before release. + * For **minor releases**: run the [`run-minor-release`](https://github.com/elastic/apm-server/actions/workflows/run-minor-release.yml) workflow (In "Use workflow from", select `main` branch. Then in "The version", specify the minor release version the release is for). + This workflow will: create a new release branch using the stack version (X.Y); update the changelog for the release branch and open a PR targeting the release branch titled `.: update docs`; create a PR on `main` titled `.: update docs, mergify, versions and changelogs`. Before merging them compare commits between latest minor and the new minor versions and ensure all relevant PRs have been included in the Changelog. If not, amend it in both PRs. Request and wait a PR review from the team before merging. After it's merged add your PR to the documentation release issue in the [`elastic/dev`](https://github.com/elastic/dev/issues?q=is%3Aissue%20state%3Aopen%20label%3Adocs) repo ([Sample Issue](https://github.com/elastic/dev/issues/2895)). + * For **major releases**: run the [`run-major-release`](https://github.com/elastic/apm-server/actions/workflows/run-major-release.yml) workflow (In "Use workflow from", select `main` branch. Then in "The version", specify the major release version the release is for). + This workflow will: create a new release branch using the stack version (X.Y); update the changelog for the release branch and open a PR targeting the release branch titled `.: update docs`; create a PR on `main` titled `.0: update docs, mergify, versions and changelogs`. Before merging them compare commits between latest minor and the new major versions and ensure all relevant PRs have been included in the Changelog. If not, amend it in both PRs. Request and wait a PR review from the team before merging. After it's merged add your PR to the documentation release issue in the [`elastic/dev`](https://github.com/elastic/dev/issues?q=is%3Aissue%20state%3Aopen%20label%3Adocs) repo ([Sample Issue](https://github.com/elastic/dev/issues/2895)). * The Release Manager will ping the team to align the release process * Update dependencies @@ -49,8 +53,8 @@ For patch releases, only the version on the existing major and minor version bra * A link to all PRs in the APM Server repository that need to be tested manually to create an overview over the PRs that need testing. Use the `test-plan` label and the version label (create it if it does not exist). For example, [this was 8.13.0 test plan](https://github.com/elastic/apm-server/issues/12822) and here you can find [all previous test plans](https://github.com/elastic/apm-server/issues?q=label%3Atest-plan+is%3Aclosed). - What we aim for is testing all functional changes applied to the new version. Review any PR updating `elastic/go-docappender` and `elastic/apm-data` dependencies, as some functional changes happens through these dependencies. - Any non-functional change or any change that is already covered by automated tests must not be included. + What we aim for is testing all functional changes applied to the new version. Review any PR updating `elastic/go-docappender` and `elastic/apm-data` dependencies, as some functional changes happens through these dependencies. + Any non-functional change or any change already covered by automated tests must not be included. * Add other test cases that require manual testing, such as test scenarios on ESS, that are not covered by automated tests or OS compatibility smoke tests for supporting new operating systems. ## Between feature freeze and release @@ -66,13 +70,24 @@ For patch releases, only the version on the existing major and minor version bra * Collaborate with the docs team on any release highlights or breaking changes that should be included in the APM Server guide. +* Run DRA for a given qualifier. The Release Team will say what qualifier to use in the the #mission-control channel. + * Go to https://buildkite.com/elastic/apm-server-package + * Click on `New Build`. + * Choose the `Branch` where the release should come from (either `main`, `8.x` or `[0-9].[0-9]+)`_ + * Click on `options` + * Add `ELASTIC_QUALIFIER=` (` [!IMPORTANT] + > Only merge the PRs once pinged on Slack by the Release Manager on release date in the #mission-control channel -* Bump the version in anticipation of the next release, e.g. [after 8.13.3 release](https://github.com/elastic/apm-server/pull/13066) bump to 8.13.4. **Prepare this PR ahead of time** but only merge it once pinged by the Release Manager on release date. +* A new [tag](https://github.com/elastic/apm-server/releases) will automatically be created on GitHub. ## When compatibility between Agents & Server changes diff --git a/docker-compose.yml b/docker-compose.yml index b32037081e5..f8c2eb13959 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -11,7 +11,7 @@ x-logging: &default-logging services: elasticsearch: # TODO: replace with a pinned version such as 9.0.0-aaaaaaaa-SNAPSHOT - image: docker.elastic.co/elasticsearch/elasticsearch:9.0.0-3b9dafe0-SNAPSHOT + image: docker.elastic.co/elasticsearch/elasticsearch:9.0.0-faf48818-SNAPSHOT ports: - 9200:9200 healthcheck: @@ -43,7 +43,7 @@ services: kibana: # TODO: replace with a pinned version such as 9.0.0-aaaaaaaa-SNAPSHOT - image: docker.elastic.co/kibana/kibana:9.0.0-3b9dafe0-SNAPSHOT + image: docker.elastic.co/kibana/kibana:9.0.0-faf48818-SNAPSHOT ports: - 5601:5601 healthcheck: @@ -63,7 +63,7 @@ services: metricbeat: # TODO: replace with a pinned version such as 9.0.0-aaaaaaaa-SNAPSHOT - image: docker.elastic.co/beats/metricbeat:9.0.0-3b9dafe0-SNAPSHOT + image: docker.elastic.co/beats/metricbeat:9.0.0-faf48818-SNAPSHOT environment: ELASTICSEARCH_HOSTS: '["http://elasticsearch:9200"]' ELASTICSEARCH_USERNAME: "${KIBANA_ES_USER:-admin}" diff --git a/docs/spec/openapi/apm-openapi.yaml b/docs/spec/openapi/apm-openapi.yaml index 34a86f7876a..06d9c5229d0 100644 --- a/docs/spec/openapi/apm-openapi.yaml +++ b/docs/spec/openapi/apm-openapi.yaml @@ -22,11 +22,6 @@ tags: The events intake API is the internal protocol that APM agents use to talk to the APM Server. x-displayName: APM event intake - - name: jaeger intake - description: > - Elastic APM natively supports Jaeger, an open-source, distributed tracing - system. - x-displayName: Jaeger event intake - name: opentelemetry intake description: > The OpenTelemetry intake API uses the OpenTelemetry Protocol (OTLP) to @@ -51,10 +46,6 @@ paths: $ref: paths/intake_v2_rum_events.yaml /intake/v3/rum/events: $ref: paths/intake_v3_rum_events.yaml - /jaeger.api_v2.CollectorService/PostSpans: - $ref: paths/jaeger.api_v2.CollectorService_PostSpans.yaml - /jaeger.api_v2.SamplingManager/GetSamplingStrategy: - $ref: paths/jaeger.api_v2.SamplingManager_GetSamplingStrategy.yaml /opentelemetry.proto.collector.metrics.v1.MetricsService/Export: $ref: paths/opentelemetry.proto.collector.metrics.v1.MetricsService_Export.yaml /opentelemetry.proto.collector.trace.v1.TraceService/Export: diff --git a/docs/spec/openapi/bundled.json b/docs/spec/openapi/bundled.json index ed6b85683fb..0badcfbf6fc 100644 --- a/docs/spec/openapi/bundled.json +++ b/docs/spec/openapi/bundled.json @@ -36,11 +36,6 @@ "description": "The events intake API is the internal protocol that APM agents use to talk to the APM Server.", "x-displayName": "APM event intake" }, - { - "name": "jaeger intake", - "description": "Elastic APM natively supports Jaeger, an open-source, distributed tracing system.\n", - "x-displayName": "Jaeger event intake" - }, { "name": "opentelemetry intake", "description": "The OpenTelemetry intake API uses the OpenTelemetry Protocol (OTLP) to send traces, metrics, and logs to APM Server. OTLP is the default transfer protocol for OpenTelemetry and is supported natively by APM Server. APM Server supports two OTLP communication protocols on the same port: OTLP/HTTP (protobuf) and OTLP/gRPC.\n", @@ -348,54 +343,6 @@ } } }, - "/jaeger.api_v2.CollectorService/PostSpans": { - "post": { - "summary": "Send Jaeger spans", - "deprecated": true, - "description": "APM Server supports receiving Jaeger spans. This API uses the gRPC protocol.\n", - "operationId": "postJaegerSpans", - "tags": [ - "jaeger intake" - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object" - } - } - } - }, - "responses": { - "200": { - "description": "OK" - } - } - } - }, - "/jaeger.api_v2.SamplingManager/GetSamplingStrategy": { - "get": { - "summary": "Get Jaeger sampling strategy", - "deprecated": true, - "description": "This API polls the APM Server for the sampling rate.\n", - "operationId": "getJaegerSampling", - "tags": [ - "jaeger intake" - ], - "responses": { - "200": { - "description": "A successful response", - "content": { - "application/json": { - "schema": { - "type": "object" - } - } - } - } - } - } - }, "/opentelemetry.proto.collector.metrics.v1.MetricsService/Export": { "post": { "summary": "Send OTLP metrics", @@ -7465,4 +7412,4 @@ } } } -} \ No newline at end of file +} diff --git a/docs/spec/openapi/bundled.yaml b/docs/spec/openapi/bundled.yaml index 19c81515229..59eb0fa03aa 100644 --- a/docs/spec/openapi/bundled.yaml +++ b/docs/spec/openapi/bundled.yaml @@ -20,10 +20,6 @@ tags: - name: event intake description: The events intake API is the internal protocol that APM agents use to talk to the APM Server. x-displayName: APM event intake - - name: jaeger intake - description: | - Elastic APM natively supports Jaeger, an open-source, distributed tracing system. - x-displayName: Jaeger event intake - name: opentelemetry intake description: | The OpenTelemetry intake API uses the OpenTelemetry Protocol (OTLP) to send traces, metrics, and logs to APM Server. OTLP is the default transfer protocol for OpenTelemetry and is supported natively by APM Server. APM Server supports two OTLP communication protocols on the same port: OTLP/HTTP (protobuf) and OTLP/gRPC. @@ -220,39 +216,6 @@ paths: responses: '202': description: Successful response; all events succeeded. - /jaeger.api_v2.CollectorService/PostSpans: - post: - summary: Send Jaeger spans - deprecated: true - description: | - APM Server supports receiving Jaeger spans. This API uses the gRPC protocol. - operationId: postJaegerSpans - tags: - - jaeger intake - requestBody: - content: - application/json: - schema: - type: object - responses: - '200': - description: OK - /jaeger.api_v2.SamplingManager/GetSamplingStrategy: - get: - summary: Get Jaeger sampling strategy - deprecated: true - description: | - This API polls the APM Server for the sampling rate. - operationId: getJaegerSampling - tags: - - jaeger intake - responses: - '200': - description: A successful response - content: - application/json: - schema: - type: object /opentelemetry.proto.collector.metrics.v1.MetricsService/Export: post: summary: Send OTLP metrics diff --git a/docs/spec/openapi/paths/jaeger.api_v2.CollectorService_PostSpans.yaml b/docs/spec/openapi/paths/jaeger.api_v2.CollectorService_PostSpans.yaml deleted file mode 100644 index 4b42cf4ca42..00000000000 --- a/docs/spec/openapi/paths/jaeger.api_v2.CollectorService_PostSpans.yaml +++ /dev/null @@ -1,16 +0,0 @@ -post: - summary: Send Jaeger spans - deprecated: true - description: | - APM Server supports receiving Jaeger spans. This API uses the gRPC protocol. - operationId: postJaegerSpans - tags: - - jaeger intake - requestBody: - content: - application/json: - schema: - type: object - responses: - '200': - description: OK diff --git a/docs/spec/openapi/paths/jaeger.api_v2.SamplingManager_GetSamplingStrategy.yaml b/docs/spec/openapi/paths/jaeger.api_v2.SamplingManager_GetSamplingStrategy.yaml deleted file mode 100644 index 0ca9546f841..00000000000 --- a/docs/spec/openapi/paths/jaeger.api_v2.SamplingManager_GetSamplingStrategy.yaml +++ /dev/null @@ -1,15 +0,0 @@ -get: - summary: Get Jaeger sampling strategy - deprecated: true - description: | - This API polls the APM Server for the sampling rate. - operationId: getJaegerSampling - tags: - - jaeger intake - responses: - '200': - description: A successful response - content: - application/json: - schema: - type: object diff --git a/docs/spec/v2/span.json b/docs/spec/v2/span.json index e86da9a69cd..14eea1b15b8 100644 --- a/docs/spec/v2/span.json +++ b/docs/spec/v2/span.json @@ -188,6 +188,9 @@ "object" ], "properties": { + "body": { + "description": "The http request body usually as a string, but may be a dictionary for multipart/form-data content" + }, "id": { "description": "ID holds the unique identifier for the http request.", "type": [ diff --git a/functionaltests/8_15_test.go b/functionaltests/8_15_test.go new file mode 100644 index 00000000000..fa787768892 --- /dev/null +++ b/functionaltests/8_15_test.go @@ -0,0 +1,165 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package functionaltests + +import ( + "context" + "testing" + "time" + + "go.uber.org/zap" + "go.uber.org/zap/zaptest" + + "github.com/elastic/apm-server/functionaltests/internal/ecclient" + "github.com/elastic/apm-server/functionaltests/internal/esclient" + "github.com/elastic/apm-server/functionaltests/internal/gen" + "github.com/elastic/apm-server/functionaltests/internal/terraform" + "github.com/elastic/go-elasticsearch/v8/typedapi/types" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestUpgrade_8_15_4_to_8_16_0(t *testing.T) { + ecAPICheck(t) + + start := time.Now() + ctx := context.Background() + + t.Log("creating deployment with terraform") + tf, err := terraform.New(t, t.Name()) + require.NoError(t, err) + ecTarget := terraform.Var("ec_target", *target) + ecRegion := terraform.Var("ec_region", regionFrom(*target)) + version := terraform.Var("stack_version", "8.15.4") + name := terraform.Var("name", t.Name()) + require.NoError(t, tf.Apply(ctx, ecTarget, ecRegion, version, name)) + t.Logf("time elapsed: %s", time.Now().Sub(start)) + + t.Cleanup(func() { + if !t.Failed() || (t.Failed() && *cleanupOnFailure) { + t.Log("cleanup terraform resources") + require.NoError(t, tf.Destroy(ctx, ecTarget, ecRegion, name, version)) + } else { + t.Log("test failed and cleanup-on-failure is false, skipping cleanup") + } + }) + + var deploymentID string + require.NoError(t, tf.Output("deployment_id", &deploymentID)) + var escfg esclient.Config + require.NoError(t, tf.Output("apm_url", &escfg.APMServerURL)) + require.NoError(t, tf.Output("es_url", &escfg.ElasticsearchURL)) + require.NoError(t, tf.Output("username", &escfg.Username)) + require.NoError(t, tf.Output("password", &escfg.Password)) + require.NoError(t, tf.Output("kb_url", &escfg.KibanaURL)) + + t.Logf("created deployment %s", escfg.KibanaURL) + + c, err := ecclient.New(endpointFrom(*target)) + require.NoError(t, err) + + ecc, err := esclient.New(escfg) + require.NoError(t, err) + + t.Log("creating APM API key") + apikey, err := ecc.CreateAPMAPIKey(ctx, t.Name()) + require.NoError(t, err) + + g := gen.New(escfg.APMServerURL, apikey) + g.Logger = zaptest.NewLogger(t, zaptest.Level(zap.InfoLevel)) + + previous, err := getDocsCountPerDS(t, ctx, ecc) + require.NoError(t, err) + + require.NoError(t, g.RunBlockingWait(ctx, c, deploymentID)) + t.Logf("time elapsed: %s", time.Now().Sub(start)) + + beforeUpgradeCount, err := getDocsCountPerDS(t, ctx, ecc) + require.NoError(t, err) + assertDocCount(t, beforeUpgradeCount, previous, expectedIngestForASingleRun()) + + t.Log("check data streams") + var dss []types.DataStream + dss, err = ecc.GetDataStream(ctx, "*apm*") + require.NoError(t, err) + assertDatastreams(t, checkDatastreamWant{ + Quantity: 8, + PreferIlm: false, + DSManagedBy: "Data stream lifecycle", + IndicesPerDs: 1, + IndicesManagedBy: []string{"Data stream lifecycle"}, + }, dss) + t.Logf("time elapsed: %s", time.Now().Sub(start)) + + t.Log("upgrade to 8.16.0") + require.NoError(t, tf.Apply(ctx, ecTarget, ecRegion, name, terraform.Var("stack_version", "8.16.0"))) + t.Logf("time elapsed: %s", time.Now().Sub(start)) + + t.Log("check number of documents after upgrade") + afterUpgradeCount, err := getDocsCountPerDS(t, ctx, ecc) + require.NoError(t, err) + // We assert that no changes happened in the number of documents after upgrade + // to ensure the state didn't change before running the next ingestion round + // and further assertions. + // We don't expect any change here unless something broke during the upgrade. + assertDocCount(t, afterUpgradeCount, esclient.APMDataStreamsDocCount{}, beforeUpgradeCount) + + t.Log("check data streams after upgrade, no rollover expected") + dss, err = ecc.GetDataStream(ctx, "*apm*") + require.NoError(t, err) + assertDatastreams(t, checkDatastreamWant{ + Quantity: 8, + PreferIlm: false, + DSManagedBy: "Data stream lifecycle", + IndicesPerDs: 1, + IndicesManagedBy: []string{"Data stream lifecycle"}, + }, dss) + + require.NoError(t, g.RunBlockingWait(ctx, c, deploymentID)) + t.Logf("time elapsed: %s", time.Now().Sub(start)) + + t.Log("check number of documents") + afterUpgradeIngestionCount, err := getDocsCountPerDS(t, ctx, ecc) + require.NoError(t, err) + assertDocCount(t, afterUpgradeIngestionCount, afterUpgradeCount, expectedIngestForASingleRun()) + + // Confirm datastreams are + // v managed by DSL if created after 8.15.0 + // x managed by ILM if created before 8.15.0 + t.Log("check data streams and verify lazy rollover happened") + dss2, err := ecc.GetDataStream(ctx, "*apm*") + require.NoError(t, err) + assertDatastreams(t, checkDatastreamWant{ + Quantity: 8, + PreferIlm: false, + DSManagedBy: "Data stream lifecycle", + IndicesPerDs: 2, + IndicesManagedBy: []string{"Data stream lifecycle", "Data stream lifecycle"}, + }, dss2) + t.Logf("time elapsed: %s", time.Now().Sub(start)) + + res, err := ecc.GetESErrorLogs(ctx) + require.NoError(t, err) + if !assert.Zero(t, res.Hits.Total.Value, "expected no error logs, but found some") { + t.Log("found error logs:") + for _, h := range res.Hits.Hits { + t.Log(string(h.Source_)) + } + } +} diff --git a/functionaltests/TestUpgrade_8_15_4_to_8_16_0/main.tf b/functionaltests/TestUpgrade_8_15_4_to_8_16_0/main.tf new file mode 100644 index 00000000000..2325c9787be --- /dev/null +++ b/functionaltests/TestUpgrade_8_15_4_to_8_16_0/main.tf @@ -0,0 +1,20 @@ +module "ec_deployment" { + source = "../../testing/infra/terraform/modules/ec_deployment" + region = var.ec_region + + deployment_template = "aws-storage-optimized" + deployment_name_prefix = var.name + + // self monitoring is enabled so we can inspect Elasticsearch + // logs from tests. + observability_deployment = "self" + + apm_server_size = "1g" + + elasticsearch_size = "4g" + elasticsearch_zone_count = 1 + + stack_version = var.stack_version + + tags = merge(local.ci_tags, module.tags.tags) +} diff --git a/functionaltests/TestUpgrade_8_15_4_to_8_16_0/outputs.tf b/functionaltests/TestUpgrade_8_15_4_to_8_16_0/outputs.tf new file mode 100644 index 00000000000..08819dbfc51 --- /dev/null +++ b/functionaltests/TestUpgrade_8_15_4_to_8_16_0/outputs.tf @@ -0,0 +1,23 @@ +output "apm_url" { + value = module.ec_deployment.apm_url +} + +output "es_url" { + value = module.ec_deployment.elasticsearch_url +} + +output "username" { + value = module.ec_deployment.elasticsearch_username +} +output "password" { + value = module.ec_deployment.elasticsearch_password + sensitive = true +} + +output "kb_url" { + value = module.ec_deployment.kibana_url +} + +output "deployment_id" { + value = module.ec_deployment.deployment_id +} diff --git a/functionaltests/TestUpgrade_8_15_4_to_8_16_0/tags.tf b/functionaltests/TestUpgrade_8_15_4_to_8_16_0/tags.tf new file mode 100644 index 00000000000..f59920ac32d --- /dev/null +++ b/functionaltests/TestUpgrade_8_15_4_to_8_16_0/tags.tf @@ -0,0 +1,20 @@ +resource "time_static" "created_date" {} + +locals { + ci_tags = { + environment = var.ENVIRONMENT + repo = var.REPO + branch = var.BRANCH + build = var.BUILD_ID + created_date = coalesce(var.CREATED_DATE, time_static.created_date.unix) + } + project = "apm-server-functionaltest" +} + +module "tags" { + source = "../../testing/infra/terraform/modules/tags" + # use the convention for team/shared owned resources if we are running in CI. + # assume this is an individually owned resource otherwise. + project = local.project +} + diff --git a/functionaltests/TestUpgrade_8_15_4_to_8_16_0/terraform.tf b/functionaltests/TestUpgrade_8_15_4_to_8_16_0/terraform.tf new file mode 100644 index 00000000000..8221f99e424 --- /dev/null +++ b/functionaltests/TestUpgrade_8_15_4_to_8_16_0/terraform.tf @@ -0,0 +1,21 @@ +terraform { + required_version = ">= 0.12.29" + + required_providers { + ec = { + source = "elastic/ec" + version = "0.5.1" + } + } +} + +locals { + api_endpoints = { + qa = "https://public-api.qa.cld.elstc.co" + pro = "https://api.elastic-cloud.com" + } +} + +provider "ec" { + endpoint = local.api_endpoints[var.ec_target] +} diff --git a/functionaltests/TestUpgrade_8_15_4_to_8_16_0/vars.tf b/functionaltests/TestUpgrade_8_15_4_to_8_16_0/vars.tf new file mode 100644 index 00000000000..a1379c5bd41 --- /dev/null +++ b/functionaltests/TestUpgrade_8_15_4_to_8_16_0/vars.tf @@ -0,0 +1,47 @@ +variable "ec_target" { + type = string + description = "The Elastic Cloud environment to target" + validation { + condition = contains(["qa", "pro"], var.ec_target) + error_message = "Valid values are (qa, pro)." + } +} + +variable "ec_region" { + type = string + description = "The Elastic Cloud region to target" +} + +variable "name" { + type = string + description = "The deployment name" +} + +variable "stack_version" { + type = string + description = "The Elasticsearch version to bootstrap" +} + +# CI variables +variable "BRANCH" { + description = "Branch name or pull request for tagging purposes" + default = "unknown-branch" +} + +variable "BUILD_ID" { + description = "Build ID in the CI for tagging purposes" + default = "unknown-build" +} + +variable "CREATED_DATE" { + description = "Creation date in epoch time for tagging purposes" + default = "" +} + +variable "ENVIRONMENT" { + default = "unknown-environment" +} + +variable "REPO" { + default = "unknown-repo-name" +} diff --git a/functionaltests/go.mod b/functionaltests/go.mod new file mode 100644 index 00000000000..0b508cd9afa --- /dev/null +++ b/functionaltests/go.mod @@ -0,0 +1,64 @@ +module github.com/elastic/apm-server/functionaltests + +go 1.23.2 + +require ( + github.com/elastic/apm-perf v0.0.0-20241230130730-2ad47482b731 + github.com/elastic/cloud-sdk-go v1.23.0 + github.com/elastic/go-elasticsearch/v8 v8.16.0 + github.com/hashicorp/terraform-exec v0.21.0 + github.com/stretchr/testify v1.10.0 + go.uber.org/zap v1.27.0 +) + +require ( + github.com/Microsoft/go-winio v0.6.2 // indirect + github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect + github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect + github.com/blang/semver/v4 v4.0.0 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/elastic/elastic-transport-go/v8 v8.6.0 // indirect + github.com/go-logr/logr v1.4.2 // indirect + github.com/go-logr/stdr v1.2.2 // indirect + github.com/go-openapi/analysis v0.21.2 // indirect + github.com/go-openapi/errors v0.20.2 // indirect + github.com/go-openapi/jsonpointer v0.19.5 // indirect + github.com/go-openapi/jsonreference v0.20.0 // indirect + github.com/go-openapi/loads v0.21.1 // indirect + github.com/go-openapi/runtime v0.23.0 // indirect + github.com/go-openapi/spec v0.20.4 // indirect + github.com/go-openapi/strfmt v0.21.2 // indirect + github.com/go-openapi/swag v0.21.1 // indirect + github.com/go-openapi/validate v0.20.3 // indirect + github.com/hashicorp/errwrap v1.1.0 // indirect + github.com/hashicorp/go-multierror v1.1.1 // indirect + github.com/hashicorp/go-version v1.6.0 // indirect + github.com/hashicorp/terraform-json v0.22.1 // indirect + github.com/josharian/intern v1.0.0 // indirect + github.com/klauspost/compress v1.17.11 // indirect + github.com/mailru/easyjson v0.7.7 // indirect + github.com/mitchellh/mapstructure v1.5.0 // indirect + github.com/oklog/ulid v1.3.1 // indirect + github.com/opentracing/opentracing-go v1.2.0 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/tidwall/gjson v1.18.0 // indirect + github.com/tidwall/match v1.1.1 // indirect + github.com/tidwall/pretty v1.2.1 // indirect + github.com/tidwall/sjson v1.2.5 // indirect + github.com/zclconf/go-cty v1.14.4 // indirect + go.elastic.co/apm/v2 v2.6.2 // indirect + go.elastic.co/fastjson v1.4.0 // indirect + go.mongodb.org/mongo-driver v1.10.0 // indirect + go.opentelemetry.io/otel v1.32.0 // indirect + go.opentelemetry.io/otel/metric v1.32.0 // indirect + go.opentelemetry.io/otel/trace v1.32.0 // indirect + go.uber.org/multierr v1.11.0 // indirect + golang.org/x/crypto v0.31.0 // indirect + golang.org/x/sync v0.10.0 // indirect + golang.org/x/sys v0.28.0 // indirect + golang.org/x/text v0.21.0 // indirect + golang.org/x/time v0.8.0 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) diff --git a/functionaltests/go.sum b/functionaltests/go.sum new file mode 100644 index 00000000000..9934b61864b --- /dev/null +++ b/functionaltests/go.sum @@ -0,0 +1,448 @@ +dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= +dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= +github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= +github.com/ProtonMail/go-crypto v1.1.0-alpha.2 h1:bkyFVUP+ROOARdgCiJzNQo2V2kiB97LyUpzH9P6Hrlg= +github.com/ProtonMail/go-crypto v1.1.0-alpha.2/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE= +github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= +github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM= +github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= +github.com/apparentlymart/go-textseg/v15 v15.0.0 h1:uYvfpb3DyLSCGWnctWKGj857c6ew1u1fNQOlOtuGxQY= +github.com/apparentlymart/go-textseg/v15 v15.0.0/go.mod h1:K8XmNZdhEBkdlyDdvbmmsvpAG721bKi0joRfFdHIWJ4= +github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= +github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= +github.com/asaskevich/govalidator v0.0.0-20200108200545-475eaeb16496/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg= +github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg= +github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= +github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so= +github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= +github.com/aws/aws-sdk-go v1.34.28/go.mod h1:H7NKnBqNVzoTJpGfLrQkkD+ytBA93eiDYi/+8rV9s48= +github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= +github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= +github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU= +github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg= +github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/elastic/apm-perf v0.0.0-20241230130730-2ad47482b731 h1:w9a+mWNmzgAUEbll5ntXB145YMYS9YNPqpm9SPkdKDY= +github.com/elastic/apm-perf v0.0.0-20241230130730-2ad47482b731/go.mod h1:9q0PpMw5QPD96OPD2Emay89Fog/jACbYjy6sWoSqEc4= +github.com/elastic/cloud-sdk-go v1.23.0 h1:IH41W2E+GIlHjuPtkNPbpYoACAJ8ffk3QiyDjUcrpgQ= +github.com/elastic/cloud-sdk-go v1.23.0/go.mod h1:k0ZebhZKX22l6Ysl5Zbpc8VLF54hfwDtHppEEEVUJ04= +github.com/elastic/elastic-transport-go/v8 v8.6.0 h1:Y2S/FBjx1LlCv5m6pWAF2kDJAHoSjSRSJCApolgfthA= +github.com/elastic/elastic-transport-go/v8 v8.6.0/go.mod h1:YLHer5cj0csTzNFXoNQ8qhtGY1GTvSqPnKWKaqQE3Hk= +github.com/elastic/go-elasticsearch/v8 v8.16.0 h1:f7bR+iBz8GTAVhwyFO3hm4ixsz2eMaEy0QroYnXV3jE= +github.com/elastic/go-elasticsearch/v8 v8.16.0/go.mod h1:lGMlgKIbYoRvay3xWBeKahAiJOgmFDsjZC39nmO3H64= +github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= +github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= +github.com/globalsign/mgo v0.0.0-20180905125535-1ca0a4f7cbcb/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= +github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= +github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI= +github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic= +github.com/go-git/go-billy/v5 v5.5.0 h1:yEY4yhzCDuMGSv83oGxiBotRzhwhNr8VZyphhiu+mTU= +github.com/go-git/go-billy/v5 v5.5.0/go.mod h1:hmexnoNsr2SJU1Ju67OaNz5ASJY3+sHgFRpCtpDCKow= +github.com/go-git/go-git/v5 v5.12.0 h1:7Md+ndsjrzZxbddRDZjF14qK+NN56sy6wkqaVrjZtys= +github.com/go-git/go-git/v5 v5.12.0/go.mod h1:FTM9VKtnI2m65hNI/TenDDDnUf2Q9FHnXYjuz9i5OEY= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= +github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/go-openapi/analysis v0.0.0-20180825180245-b006789cd277/go.mod h1:k70tL6pCuVxPJOHXQ+wIac1FUrvNkHolPie/cLEU6hI= +github.com/go-openapi/analysis v0.17.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik= +github.com/go-openapi/analysis v0.18.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik= +github.com/go-openapi/analysis v0.19.2/go.mod h1:3P1osvZa9jKjb8ed2TPng3f0i/UY9snX6gxi44djMjk= +github.com/go-openapi/analysis v0.19.4/go.mod h1:3P1osvZa9jKjb8ed2TPng3f0i/UY9snX6gxi44djMjk= +github.com/go-openapi/analysis v0.19.5/go.mod h1:hkEAkxagaIvIP7VTn8ygJNkd4kAYON2rCu0v0ObL0AU= +github.com/go-openapi/analysis v0.19.10/go.mod h1:qmhS3VNFxBlquFJ0RGoDtylO9y4pgTAUNE9AEEMdlJQ= +github.com/go-openapi/analysis v0.19.16/go.mod h1:GLInF007N83Ad3m8a/CbQ5TPzdnGT7workfHwuVjNVk= +github.com/go-openapi/analysis v0.20.0/go.mod h1:BMchjvaHDykmRMsK40iPtvyOfFdMMxlOmQr9FBZk+Og= +github.com/go-openapi/analysis v0.20.1/go.mod h1:BMchjvaHDykmRMsK40iPtvyOfFdMMxlOmQr9FBZk+Og= +github.com/go-openapi/analysis v0.21.2 h1:hXFrOYFHUAMQdu6zwAiKKJHJQ8kqZs1ux/ru1P1wLJU= +github.com/go-openapi/analysis v0.21.2/go.mod h1:HZwRk4RRisyG8vx2Oe6aqeSQcoxRp47Xkp3+K6q+LdY= +github.com/go-openapi/errors v0.17.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0= +github.com/go-openapi/errors v0.18.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0= +github.com/go-openapi/errors v0.19.2/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA4kxxpKBC94= +github.com/go-openapi/errors v0.19.3/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA4kxxpKBC94= +github.com/go-openapi/errors v0.19.6/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= +github.com/go-openapi/errors v0.19.7/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= +github.com/go-openapi/errors v0.19.8/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= +github.com/go-openapi/errors v0.19.9/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= +github.com/go-openapi/errors v0.20.1/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= +github.com/go-openapi/errors v0.20.2 h1:dxy7PGTqEh94zj2E3h1cUmQQWiM1+aeCROfAr02EmK8= +github.com/go-openapi/errors v0.20.2/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= +github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= +github.com/go-openapi/jsonpointer v0.18.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= +github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg= +github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY= +github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= +github.com/go-openapi/jsonreference v0.18.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= +github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc= +github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8= +github.com/go-openapi/jsonreference v0.19.5/go.mod h1:RdybgQwPxbL4UEjuAruzK1x3nE69AqPYEJeo/TWfEeg= +github.com/go-openapi/jsonreference v0.19.6/go.mod h1:diGHMEHg2IqXZGKxqyvWdfWU/aim5Dprw5bqpKkTvns= +github.com/go-openapi/jsonreference v0.20.0 h1:MYlu0sBgChmCfJxxUKZ8g1cPWFOB37YSZqewK7OKeyA= +github.com/go-openapi/jsonreference v0.20.0/go.mod h1:Ag74Ico3lPc+zR+qjn4XBUmXymS4zJbYVCZmcgkasdo= +github.com/go-openapi/loads v0.17.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= +github.com/go-openapi/loads v0.18.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= +github.com/go-openapi/loads v0.19.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= +github.com/go-openapi/loads v0.19.2/go.mod h1:QAskZPMX5V0C2gvfkGZzJlINuP7Hx/4+ix5jWFxsNPs= +github.com/go-openapi/loads v0.19.3/go.mod h1:YVfqhUCdahYwR3f3iiwQLhicVRvLlU/WO5WPaZvcvSI= +github.com/go-openapi/loads v0.19.5/go.mod h1:dswLCAdonkRufe/gSUC3gN8nTSaB9uaS2es0x5/IbjY= +github.com/go-openapi/loads v0.19.6/go.mod h1:brCsvE6j8mnbmGBh103PT/QLHfbyDxA4hsKvYBNEGVc= +github.com/go-openapi/loads v0.19.7/go.mod h1:brCsvE6j8mnbmGBh103PT/QLHfbyDxA4hsKvYBNEGVc= +github.com/go-openapi/loads v0.20.0/go.mod h1:2LhKquiE513rN5xC6Aan6lYOSddlL8Mp20AW9kpviM4= +github.com/go-openapi/loads v0.20.2/go.mod h1:hTVUotJ+UonAMMZsvakEgmWKgtulweO9vYP2bQYKA/o= +github.com/go-openapi/loads v0.21.0/go.mod h1:rHYve9nZrQ4CJhyeIIFJINGCg1tQpx2yJrrNo8sf1ws= +github.com/go-openapi/loads v0.21.1 h1:Wb3nVZpdEzDTcly8S4HMkey6fjARRzb7iEaySimlDW0= +github.com/go-openapi/loads v0.21.1/go.mod h1:/DtAMXXneXFjbQMGEtbamCZb+4x7eGwkvZCvBmwUG+g= +github.com/go-openapi/runtime v0.0.0-20180920151709-4f900dc2ade9/go.mod h1:6v9a6LTXWQCdL8k1AO3cvqx5OtZY/Y9wKTgaoP6YRfA= +github.com/go-openapi/runtime v0.19.0/go.mod h1:OwNfisksmmaZse4+gpV3Ne9AyMOlP1lt4sK4FXt0O64= +github.com/go-openapi/runtime v0.19.4/go.mod h1:X277bwSUBxVlCYR3r7xgZZGKVvBd/29gLDlFGtJ8NL4= +github.com/go-openapi/runtime v0.19.15/go.mod h1:dhGWCTKRXlAfGnQG0ONViOZpjfg0m2gUt9nTQPQZuoo= +github.com/go-openapi/runtime v0.19.16/go.mod h1:5P9104EJgYcizotuXhEuUrzVc+j1RiSjahULvYmlv98= +github.com/go-openapi/runtime v0.19.24/go.mod h1:Lm9YGCeecBnUUkFTxPC4s1+lwrkJ0pthx8YvyjCfkgk= +github.com/go-openapi/runtime v0.23.0 h1:HX6ET2sHCIvaKeDDQoU01CtO1ekg5EkekHSkLTtWXH0= +github.com/go-openapi/runtime v0.23.0/go.mod h1:aQg+kaIQEn+A2CRSY1TxbM8+sT9g2V3aLc1FbIAnbbs= +github.com/go-openapi/spec v0.17.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= +github.com/go-openapi/spec v0.18.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= +github.com/go-openapi/spec v0.19.2/go.mod h1:sCxk3jxKgioEJikev4fgkNmwS+3kuYdJtcsZsD5zxMY= +github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo= +github.com/go-openapi/spec v0.19.6/go.mod h1:Hm2Jr4jv8G1ciIAo+frC/Ft+rR2kQDh8JHKHb3gWUSk= +github.com/go-openapi/spec v0.19.8/go.mod h1:Hm2Jr4jv8G1ciIAo+frC/Ft+rR2kQDh8JHKHb3gWUSk= +github.com/go-openapi/spec v0.19.15/go.mod h1:+81FIL1JwC5P3/Iuuozq3pPE9dXdIEGxFutcFKaVbmU= +github.com/go-openapi/spec v0.20.0/go.mod h1:+81FIL1JwC5P3/Iuuozq3pPE9dXdIEGxFutcFKaVbmU= +github.com/go-openapi/spec v0.20.1/go.mod h1:93x7oh+d+FQsmsieroS4cmR3u0p/ywH649a3qwC9OsQ= +github.com/go-openapi/spec v0.20.3/go.mod h1:gG4F8wdEDN+YPBMVnzE85Rbhf+Th2DTvA9nFPQ5AYEg= +github.com/go-openapi/spec v0.20.4 h1:O8hJrt0UMnhHcluhIdUgCLRWyM2x7QkBXRvOs7m+O1M= +github.com/go-openapi/spec v0.20.4/go.mod h1:faYFR1CvsJZ0mNsmsphTMSoRrNV3TEDoAM7FOEWeq8I= +github.com/go-openapi/strfmt v0.17.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU= +github.com/go-openapi/strfmt v0.18.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU= +github.com/go-openapi/strfmt v0.19.0/go.mod h1:+uW+93UVvGGq2qGaZxdDeJqSAqBqBdl+ZPMF/cC8nDY= +github.com/go-openapi/strfmt v0.19.2/go.mod h1:0yX7dbo8mKIvc3XSKp7MNfxw4JytCfCD6+bY1AVL9LU= +github.com/go-openapi/strfmt v0.19.3/go.mod h1:0yX7dbo8mKIvc3XSKp7MNfxw4JytCfCD6+bY1AVL9LU= +github.com/go-openapi/strfmt v0.19.4/go.mod h1:eftuHTlB/dI8Uq8JJOyRlieZf+WkkxUuk0dgdHXr2Qk= +github.com/go-openapi/strfmt v0.19.5/go.mod h1:eftuHTlB/dI8Uq8JJOyRlieZf+WkkxUuk0dgdHXr2Qk= +github.com/go-openapi/strfmt v0.19.11/go.mod h1:UukAYgTaQfqJuAFlNxxMWNvMYiwiXtLsF2VwmoFtbtc= +github.com/go-openapi/strfmt v0.20.0/go.mod h1:UukAYgTaQfqJuAFlNxxMWNvMYiwiXtLsF2VwmoFtbtc= +github.com/go-openapi/strfmt v0.20.2/go.mod h1:43urheQI9dNtE5lTZQfuFJvjYJKPrxicATpEfZwHUNk= +github.com/go-openapi/strfmt v0.21.0/go.mod h1:ZRQ409bWMj+SOgXofQAGTIo2Ebu72Gs+WaRADcS5iNg= +github.com/go-openapi/strfmt v0.21.2 h1:5NDNgadiX1Vhemth/TH4gCGopWSTdDjxl60H3B7f+os= +github.com/go-openapi/strfmt v0.21.2/go.mod h1:I/XVKeLc5+MM5oPNN7P6urMOpuLXEcNrCX/rPGuWb0k= +github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= +github.com/go-openapi/swag v0.18.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= +github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= +github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= +github.com/go-openapi/swag v0.19.7/go.mod h1:ao+8BpOPyKdpQz3AOJfbeEVpLmWAvlT1IfTe5McPyhY= +github.com/go-openapi/swag v0.19.9/go.mod h1:ao+8BpOPyKdpQz3AOJfbeEVpLmWAvlT1IfTe5McPyhY= +github.com/go-openapi/swag v0.19.12/go.mod h1:eFdyEBkTdoAf/9RXBvj4cr1nH7GD8Kzo5HTt47gr72M= +github.com/go-openapi/swag v0.19.13/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= +github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= +github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= +github.com/go-openapi/swag v0.21.1 h1:wm0rhTb5z7qpJRHBdPOMuY4QjVUMbF6/kwoYeRAOrKU= +github.com/go-openapi/swag v0.21.1/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= +github.com/go-openapi/validate v0.18.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4= +github.com/go-openapi/validate v0.19.2/go.mod h1:1tRCw7m3jtI8eNWEEliiAqUIcBztB2KDnRCRMUi7GTA= +github.com/go-openapi/validate v0.19.3/go.mod h1:90Vh6jjkTn+OT1Eefm0ZixWNFjhtOH7vS9k0lo6zwJo= +github.com/go-openapi/validate v0.19.10/go.mod h1:RKEZTUWDkxKQxN2jDT7ZnZi2bhZlbNMAuKvKB+IaGx8= +github.com/go-openapi/validate v0.19.12/go.mod h1:Rzou8hA/CBw8donlS6WNEUQupNvUZ0waH08tGe6kAQ4= +github.com/go-openapi/validate v0.19.15/go.mod h1:tbn/fdOwYHgrhPBzidZfJC2MIVvs9GA7monOmWBbeCI= +github.com/go-openapi/validate v0.20.1/go.mod h1:b60iJT+xNNLfaQJUqLI7946tYiFEOuE9E4k54HpKcJ0= +github.com/go-openapi/validate v0.20.3 h1:GZPPhhKSZrE8HjB4eEkoYAZmoWA4+tCemSgINH1/vKw= +github.com/go-openapi/validate v0.20.3/go.mod h1:goDdqVGiigM3jChcrYJxD2joalke3ZXeftD16byIjA4= +github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0= +github.com/gobuffalo/depgen v0.0.0-20190329151759-d478694a28d3/go.mod h1:3STtPUQYuzV0gBVOY3vy6CfMm/ljR4pABfrTeHNLHUY= +github.com/gobuffalo/depgen v0.1.0/go.mod h1:+ifsuy7fhi15RWncXQQKjWS9JPkdah5sZvtHc2RXGlg= +github.com/gobuffalo/envy v1.6.15/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= +github.com/gobuffalo/envy v1.7.0/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= +github.com/gobuffalo/flect v0.1.0/go.mod h1:d2ehjJqGOH/Kjqcoz+F7jHTBbmDb38yXA598Hb50EGs= +github.com/gobuffalo/flect v0.1.1/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI= +github.com/gobuffalo/flect v0.1.3/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI= +github.com/gobuffalo/genny v0.0.0-20190329151137-27723ad26ef9/go.mod h1:rWs4Z12d1Zbf19rlsn0nurr75KqhYp52EAGGxTbBhNk= +github.com/gobuffalo/genny v0.0.0-20190403191548-3ca520ef0d9e/go.mod h1:80lIj3kVJWwOrXWWMRzzdhW3DsrdjILVil/SFKBzF28= +github.com/gobuffalo/genny v0.1.0/go.mod h1:XidbUqzak3lHdS//TPu2OgiFB+51Ur5f7CSnXZ/JDvo= +github.com/gobuffalo/genny v0.1.1/go.mod h1:5TExbEyY48pfunL4QSXxlDOmdsD44RRq4mVZ0Ex28Xk= +github.com/gobuffalo/gitgen v0.0.0-20190315122116-cc086187d211/go.mod h1:vEHJk/E9DmhejeLeNt7UVvlSGv3ziL+djtTr3yyzcOw= +github.com/gobuffalo/gogen v0.0.0-20190315121717-8f38393713f5/go.mod h1:V9QVDIxsgKNZs6L2IYiGR8datgMhB577vzTDqypH360= +github.com/gobuffalo/gogen v0.1.0/go.mod h1:8NTelM5qd8RZ15VjQTFkAW6qOMx5wBbW4dSCS3BY8gg= +github.com/gobuffalo/gogen v0.1.1/go.mod h1:y8iBtmHmGc4qa3urIyo1shvOD8JftTtfcKi+71xfDNE= +github.com/gobuffalo/logger v0.0.0-20190315122211-86e12af44bc2/go.mod h1:QdxcLw541hSGtBnhUc4gaNIXRjiDppFGaDqzbrBd3v8= +github.com/gobuffalo/mapi v1.0.1/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc= +github.com/gobuffalo/mapi v1.0.2/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc= +github.com/gobuffalo/packd v0.0.0-20190315124812-a385830c7fc0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4= +github.com/gobuffalo/packd v0.1.0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4= +github.com/gobuffalo/packr/v2 v2.0.9/go.mod h1:emmyGweYTm6Kdper+iywB6YK5YzuKchGtJQZ0Odn4pQ= +github.com/gobuffalo/packr/v2 v2.2.0/go.mod h1:CaAwI0GPIAv+5wKLtv8Afwl+Cm78K/I/VCm/3ptBN+0= +github.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= +github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= +github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= +github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= +github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= +github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek= +github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/hc-install v0.6.4 h1:QLqlM56/+SIIGvGcfFiwMY3z5WGXT066suo/v9Km8e0= +github.com/hashicorp/hc-install v0.6.4/go.mod h1:05LWLy8TD842OtgcfBbOT0WMoInBMUSHjmDx10zuBIA= +github.com/hashicorp/terraform-exec v0.21.0 h1:uNkLAe95ey5Uux6KJdua6+cv8asgILFVWkd/RG0D2XQ= +github.com/hashicorp/terraform-exec v0.21.0/go.mod h1:1PPeMYou+KDUSSeRE9szMZ/oHf4fYUmB923Wzbq1ICg= +github.com/hashicorp/terraform-json v0.22.1 h1:xft84GZR0QzjPVWs4lRUwvTcPnegqlyS7orfb5Ltvec= +github.com/hashicorp/terraform-json v0.22.1/go.mod h1:JbWSQCLFSXFFhg42T7l9iJwdGXBYV8fmmD6o/ML4p3A= +github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= +github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= +github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= +github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= +github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= +github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= +github.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaRPx4tDPEn4= +github.com/karrick/godirwalk v1.10.3/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA= +github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4= +github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= +github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= +github.com/klauspost/compress v1.9.5/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= +github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= +github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc= +github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.7.1/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= +github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE= +github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0= +github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.3.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/mapstructure v1.4.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= +github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4= +github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= +github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= +github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= +github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= +github.com/pelletier/go-toml v1.4.0/go.mod h1:PN7xzY2wHTK0K9p34ErDQMlFxa51Fk0OUruD3k1mMwo= +github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE= +github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4= +github.com/pjbgf/sha1cd v0.3.0/go.mod h1:nZ1rrWOcGJ5uZgEEVL1VUM9iRQiZvWdbZjkKyFzPPsI= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= +github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8= +github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= +github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= +github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/skeema/knownhosts v1.2.2 h1:Iug2P4fLmDw9f41PB6thxUkNUkJzB5i+1/exaj40L3A= +github.com/skeema/knownhosts v1.2.2/go.mod h1:xYbVRSPxqBZFrdmDyMmsOs+uX1UZC3nTN3ThzgDxUwo= +github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= +github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= +github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY= +github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= +github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= +github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= +github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= +github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= +github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4= +github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= +github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= +github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= +github.com/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv3vaXspKw= +github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= +github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= +github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= +github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs= +github.com/xdg-go/scram v1.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g= +github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM= +github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8= +github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I= +github.com/xdg/stringprep v0.0.0-20180714160509-73f8eece6fdc/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y= +github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= +github.com/zclconf/go-cty v1.14.4 h1:uXXczd9QDGsgu0i/QFR/hzI5NYCHLf6NQw/atrbnhq8= +github.com/zclconf/go-cty v1.14.4/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE= +go.elastic.co/apm/v2 v2.6.2 h1:VBplAxgbOgTv+Giw/FS91xJpHYw/q8fz/XKPvqC+7/o= +go.elastic.co/apm/v2 v2.6.2/go.mod h1:33rOXgtHwbgZcDgi6I/GtCSMZQqgxkHC0IQT3gudKvo= +go.elastic.co/fastjson v1.4.0 h1:a4BXUKXZHAzjVOPrqtEx2FDsIRBCMek01vCnrtyutWs= +go.elastic.co/fastjson v1.4.0/go.mod h1:ZD5um63l0/8TIdddZbL2znD83FAr2IckYa3KR7VcdNA= +go.mongodb.org/mongo-driver v1.0.3/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= +go.mongodb.org/mongo-driver v1.1.1/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= +go.mongodb.org/mongo-driver v1.3.0/go.mod h1:MSWZXKOynuguX+JSvwP8i+58jYCXxbia8HS3gZBapIE= +go.mongodb.org/mongo-driver v1.3.4/go.mod h1:MSWZXKOynuguX+JSvwP8i+58jYCXxbia8HS3gZBapIE= +go.mongodb.org/mongo-driver v1.4.3/go.mod h1:WcMNYLx/IlOxLe6JRJiv2uXuCz6zBLndR4SoGjYphSc= +go.mongodb.org/mongo-driver v1.4.4/go.mod h1:WcMNYLx/IlOxLe6JRJiv2uXuCz6zBLndR4SoGjYphSc= +go.mongodb.org/mongo-driver v1.4.6/go.mod h1:WcMNYLx/IlOxLe6JRJiv2uXuCz6zBLndR4SoGjYphSc= +go.mongodb.org/mongo-driver v1.5.1/go.mod h1:gRXCHX4Jo7J0IJ1oDQyUxF7jfy19UfxniMS4xxMmUqw= +go.mongodb.org/mongo-driver v1.7.3/go.mod h1:NqaYOwnXWr5Pm7AOpO5QFxKJ503nbMse/R79oO62zWg= +go.mongodb.org/mongo-driver v1.7.5/go.mod h1:VXEWRZ6URJIkUq2SCAyapmhH0ZLRBP+FT4xhp5Zvxng= +go.mongodb.org/mongo-driver v1.10.0 h1:UtV6N5k14upNp4LTduX0QCufG124fSu25Wz9tu94GLg= +go.mongodb.org/mongo-driver v1.10.0/go.mod h1:wsihk0Kdgv8Kqu1Anit4sfK+22vSFbUrAVEYRhCXrA8= +go.opentelemetry.io/otel v1.32.0 h1:WnBN+Xjcteh0zdk01SVqV55d/m62NJLJdIyb4y/WO5U= +go.opentelemetry.io/otel v1.32.0/go.mod h1:00DCVSB0RQcnzlwyTfqtxSm+DRr9hpYrHjNGiBHVQIg= +go.opentelemetry.io/otel/metric v1.32.0 h1:xV2umtmNcThh2/a/aCP+h64Xx5wsj8qqnkYZktzNa0M= +go.opentelemetry.io/otel/metric v1.32.0/go.mod h1:jH7CIbbK6SH2V2wE16W05BHCtIDzauciCRLoc/SyMv8= +go.opentelemetry.io/otel/sdk v1.32.0 h1:RNxepc9vK59A8XsgZQouW8ue8Gkb4jpWtJm9ge5lEG4= +go.opentelemetry.io/otel/sdk v1.32.0/go.mod h1:LqgegDBjKMmb2GC6/PrTnteJG39I8/vJCAP9LlJXEjU= +go.opentelemetry.io/otel/trace v1.32.0 h1:WIC9mYrXf8TmY/EXuULKc8hR17vE+Hjv2cssQDe03fM= +go.opentelemetry.io/otel/trace v1.32.0/go.mod h1:+i4rkvCraA+tG6AzwloGaCtkx53Fa+L+V8e9a7YvhT8= +go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= +go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= +go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= +go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= +go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190422162423-af44ce270edf/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= +golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190617133340-57b3e21c3d56/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= +golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= +golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= +golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190320064053-1272bf9dcd53/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4= +golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190412183630-56d357773e84/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= +golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190321052220-f7bb7a8bee54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190419153524-e8e3143a4f4a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190531175056-4c3a928424d2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= +golang.org/x/time v0.8.0 h1:9i3RxcPv3PZnitoVGMPDKZSq1xW1gK1Xy3ArNOGZfEg= +golang.org/x/time v0.8.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190125232054-d66bd3c5d5a6/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190329151228-23e29df326fe/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190416151739-9c9e1878f421/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190420181800-aa740d480789/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190531172133-b3315ee88b7d/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190617190820-da514acc4774/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= +gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/functionaltests/internal/ecclient/client.go b/functionaltests/internal/ecclient/client.go new file mode 100644 index 00000000000..5b1cdcfdc36 --- /dev/null +++ b/functionaltests/internal/ecclient/client.go @@ -0,0 +1,132 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package ecclient + +import ( + "context" + "fmt" + "io" + "net/http" + "os" + "time" + + "github.com/elastic/cloud-sdk-go/pkg/api" + "github.com/elastic/cloud-sdk-go/pkg/api/deploymentapi" + "github.com/elastic/cloud-sdk-go/pkg/auth" + "github.com/elastic/cloud-sdk-go/pkg/client/deployments" +) + +type Client struct { + *api.API + endpoint string +} + +func New(endpoint string) (*Client, error) { + apiKey := os.Getenv("EC_API_KEY") + if apiKey == "" { + return nil, fmt.Errorf("unable to obtain value from EC_API_KEY environment variable") + } + + if endpoint == "" { + return nil, fmt.Errorf("endpoint is required") + } + + ess, err := api.NewAPI(api.Config{ + AuthWriter: auth.APIKey(apiKey), + Client: new(http.Client), + Host: endpoint, + }) + if err != nil { + return nil, fmt.Errorf("cannot create Elastic Cloud API client: %w", err) + } + + c := Client{ess, endpoint} + + return &c, nil +} + +func (c *Client) RestartIntegrationServer(ctx context.Context, deploymentID string) error { + res, err := deploymentapi.Get(deploymentapi.GetParams{ + API: c.API, + DeploymentID: deploymentID, + }) + if err != nil { + + return fmt.Errorf("cannot retrieve ref id of integrations server for deployment %s: %w", deploymentID, err) + } + + refID := *res.Resources.IntegrationsServer[0].RefID + + // This is an undocumented API, but it works. + // Is like https://www.elastic.co/docs/api/doc/cloud/operation/operation-restart-deployment-es-resource + // but using integrations_server instead of elasticsearch. integrations_server is the expected Kind for + // the 8.x APM server setup on Elastic Cloud. + url := fmt.Sprintf("%s/api/v1/deployments/%s/integrations_server/%s/_restart", c.endpoint, deploymentID, refID) + req, err := http.NewRequest(http.MethodPost, url, nil) + if err != nil { + return fmt.Errorf("cannot create integrations server restart request for deployment %s: %w", deploymentID, err) + } + + req = c.API.AuthWriter.AuthRequest(req) + resp, err := http.DefaultClient.Do(req) + if err != nil { + return fmt.Errorf("cannot execute HTTP request for restarting deployment %s: %w", deploymentID, err) + } + defer resp.Body.Close() + + if resp.StatusCode != http.StatusAccepted { + b, err := io.ReadAll(resp.Body) + if err != nil { + return fmt.Errorf("cannot read body after receiving a %d response while restarting integrations server: %w", resp.StatusCode, err) + } + return fmt.Errorf("restarting integrations server returned %d response with content: %s", resp.StatusCode, b) + } + + // Wait until the integration server is back online. + status := func() (string, error) { + r, err := c.API.V1API.Deployments.GetDeploymentIntegrationsServerResourceInfo( + deployments.NewGetDeploymentIntegrationsServerResourceInfoParams(). + WithDeploymentID(deploymentID). + WithRefID(refID), + c.API.AuthWriter) + if err != nil { + return "", err + } + + return *r.Payload.Info.Status, nil + } + timeout := 10 * time.Minute + ticker := time.NewTicker(10 * time.Second) + defer ticker.Stop() + tctx, cancel := context.WithTimeout(ctx, timeout) + defer cancel() + for { + select { + case <-tctx.Done(): + return fmt.Errorf("timeout reached waiting for integrations server to restart") + case <-ticker.C: + s, err := status() + if err != nil { + return fmt.Errorf("cannot retrieve integrations server status: %w", err) + } + if s == "started" { + return nil + } + } + } +} diff --git a/functionaltests/internal/esclient/client.go b/functionaltests/internal/esclient/client.go new file mode 100644 index 00000000000..76b7028310e --- /dev/null +++ b/functionaltests/internal/esclient/client.go @@ -0,0 +1,190 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package esclient + +import ( + "context" + "crypto/tls" + "encoding/json" + "errors" + "fmt" + "net/http" + "time" + + "github.com/elastic/go-elasticsearch/v8" + "github.com/elastic/go-elasticsearch/v8/typedapi/core/search" + "github.com/elastic/go-elasticsearch/v8/typedapi/esql/query" + "github.com/elastic/go-elasticsearch/v8/typedapi/security/createapikey" + "github.com/elastic/go-elasticsearch/v8/typedapi/types" +) + +type Client struct { + es *elasticsearch.TypedClient +} + +// New returns a new Client for querying APM data. +func New(cfg Config) (*Client, error) { + transport := http.DefaultTransport.(*http.Transport).Clone() + transport.TLSClientConfig = &tls.Config{InsecureSkipVerify: cfg.TLSSkipVerify} + + es, err := elasticsearch.NewTypedClient(elasticsearch.Config{ + Addresses: []string{cfg.ElasticsearchURL}, + Username: cfg.Username, + APIKey: cfg.APIKey, + Password: cfg.Password, + Transport: transport, + }) + if err != nil { + return nil, fmt.Errorf("error creating Elasticsearch client: %w", err) + } + return &Client{ + es: es, + }, nil +} + +var elasticsearchTimeUnits = []struct { + Duration time.Duration + Unit string +}{ + {time.Hour, "h"}, + {time.Minute, "m"}, + {time.Second, "s"}, + {time.Millisecond, "ms"}, + {time.Microsecond, "micros"}, +} + +// formatDurationElasticsearch formats a duration using +// Elasticsearch supported time units. +// +// See https://www.elastic.co/guide/en/elasticsearch/reference/current/api-conventions.html#time-units +func formatDurationElasticsearch(d time.Duration) string { + for _, tu := range elasticsearchTimeUnits { + if d%tu.Duration == 0 { + return fmt.Sprintf("%d%s", d/tu.Duration, tu.Unit) + } + } + return fmt.Sprintf("%dnanos", d) +} + +// CreateAgentAPIKey creates an agent API Key, and returns it in the +// base64-encoded form that agents should provide. +// +// If expiration is less than or equal to zero, then the API Key never expires. +func (c *Client) CreateAPIKey(ctx context.Context, name string, expiration time.Duration, roles map[string]types.RoleDescriptor) (string, error) { + var maybeExpiration types.Duration + if expiration > 0 { + maybeExpiration = formatDurationElasticsearch(expiration) + } + resp, err := c.es.Security.CreateApiKey().Request(&createapikey.Request{ + Name: &name, + Expiration: maybeExpiration, + RoleDescriptors: roles, + Metadata: map[string]json.RawMessage{ + "creator": []byte(`"apmclient"`), + }, + }).Do(ctx) + if err != nil { + return "", fmt.Errorf("error creating API Key: %w", err) + } + return resp.Encoded, nil +} + +func (c *Client) CreateAPMAPIKey(ctx context.Context, name string) (string, error) { + return c.CreateAPIKey(context.Background(), + name, -1, map[string]types.RoleDescriptor{}, + ) +} + +func (c *Client) GetDataStream(ctx context.Context, name string) ([]types.DataStream, error) { + resp, err := c.es.Indices.GetDataStream().Name(name).Do(ctx) + if err != nil { + return []types.DataStream{}, fmt.Errorf("cannot GET datastream: %w", err) + } + + return resp.DataStreams, nil +} + +// ApmDocCount is used to unmarshal response from ES|QL query in ApmDocCount(). +type ApmDocCount struct { + Count int + Datastream string +} + +// APMDataStreamsDocCount is an easy to assert on format reporting doc count for +// APM data streams. +type APMDataStreamsDocCount map[string]int + +func (c *Client) ApmDocCount(ctx context.Context) (APMDataStreamsDocCount, error) { + q := `FROM traces-apm*,apm-*,traces-*.otel-*,logs-apm*,apm-*,logs-*.otel-*,metrics-apm*,apm-*,metrics-*.otel-* +| EVAL datastream = CONCAT(data_stream.type, "-", data_stream.dataset, "-", data_stream.namespace) +| STATS count = COUNT(*) BY datastream +| SORT count DESC` + + qry := c.es.Esql.Query().Query(q) + resp, err := query.Helper[ApmDocCount](ctx, qry) + if err != nil { + var eserr *types.ElasticsearchError + // suppress this error as it only indicates no data is available yet. + expected := `Found 1 problem +line 1:1: Unknown index [traces-apm*,apm-*,traces-*.otel-*,logs-apm*,apm-*,logs-*.otel-*,metrics-apm*,apm-*,metrics-*.otel-*]` + if errors.As(err, &eserr) && + eserr.ErrorCause.Reason != nil && + *eserr.ErrorCause.Reason == expected { + return APMDataStreamsDocCount{}, nil + } + + return APMDataStreamsDocCount{}, fmt.Errorf("cannot retrieve APM doc count: %w", err) + } + + res := APMDataStreamsDocCount{} + for _, dc := range resp { + res[dc.Datastream] = dc.Count + } + + return res, nil +} + +// GetESErrorLogs retrieves Elasticsearch error logs. +// The search query is on the Index used by Elasticsearch monitoring to store logs. +func (c *Client) GetESErrorLogs(ctx context.Context) (*search.Response, error) { + res, err := c.es.Search(). + Index("elastic-cloud-logs-8"). + Request(&search.Request{ + Query: &types.Query{ + Bool: &types.BoolQuery{ + Must: []types.Query{ + { + Match: map[string]types.MatchQuery{ + "service.type": {Query: "elasticsearch"}, + }, + }, + { + Match: map[string]types.MatchQuery{ + "log.level": {Query: "ERROR"}, + }, + }, + }, + }, + }, + }).Do(ctx) + if err != nil { + return search.NewResponse(), fmt.Errorf("cannot run search query: %w", err) + } + + return res, nil +} diff --git a/functionaltests/internal/esclient/config.go b/functionaltests/internal/esclient/config.go new file mode 100644 index 00000000000..b987a1c34a9 --- /dev/null +++ b/functionaltests/internal/esclient/config.go @@ -0,0 +1,54 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package esclient + +type Config struct { + // ElasticsearchURL holds the Elasticsearch URL. + ElasticsearchURL string + + // Username holds the Elasticsearch username for basic auth. + Username string + + // Password holds the Elasticsearch password for basic auth. + Password string + + // APIKey holds an Elasticsearch API Key. + // + // This will be set from $ELASTICSEARCH_API_KEY if specified. + APIKey string + + // APMServerURL holds the APM Server URL. + // + // If this is unspecified, it will be derived from + // ElasticsearchURL if that is an Elastic Cloud URL. + APMServerURL string + + // KibanaURL holds the Kibana URL. + // + // If this is unspecified, it will be derived from + // ElasticsearchURL if that is an Elastic Cloud URL. + KibanaURL string + + // TLSSkipVerify determines if TLS certificate + // verification is skipped or not. Default to false. + // + // If not specified the value will be take from + // TLS_SKIP_VERIFY env var. + // Any value different from "" is considered true. + TLSSkipVerify bool +} diff --git a/functionaltests/internal/gen/generator.go b/functionaltests/internal/gen/generator.go new file mode 100644 index 00000000000..ea830261caf --- /dev/null +++ b/functionaltests/internal/gen/generator.go @@ -0,0 +1,84 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package gen + +import ( + "context" + "fmt" + "net/url" + + "go.uber.org/zap" + + "github.com/elastic/apm-perf/pkg/telemetrygen" + "github.com/elastic/apm-server/functionaltests/internal/ecclient" +) + +type Generator struct { + Logger *zap.Logger + APMAPIKey string + APMServerURL string + EventRate string +} + +func New(url, apikey string) *Generator { + return &Generator{ + Logger: zap.NewNop(), + APMAPIKey: apikey, + APMServerURL: url, + EventRate: "1000/s", + } +} + +// RunBlocking runs the underlying generator in blocking mode. +func (g *Generator) RunBlocking(ctx context.Context) error { + cfg := telemetrygen.DefaultConfig() + cfg.APIKey = g.APMAPIKey + + u, err := url.Parse(g.APMServerURL) + if err != nil { + return fmt.Errorf("cannot parse APM server URL: %w", err) + } + cfg.ServerURL = u + + cfg.EventRate.Set(g.EventRate) + gen, err := telemetrygen.New(cfg) + if err != nil { + return fmt.Errorf("cannot create telemetrygen Generator: %w", err) + } + + g.Logger.Info("ingest data") + gen.Logger = g.Logger + return gen.RunBlocking(ctx) +} + +// RunBlockingWait runs the underlying generator in blocking mode and waits until the +// cluster Integrations Server has been restarted. +// Restarting APM Server ensures all data, including aggregations, in flushed before +// shutdown, ensuring ingestion and 1m aggregations to be completed. +func (g *Generator) RunBlockingWait(ctx context.Context, c *ecclient.Client, deploymentID string) error { + if err := g.RunBlocking(ctx); err != nil { + return fmt.Errorf("cannot run generator: %w", err) + } + + g.Logger.Info("restarting integrations server to flush apm server data") + if err := c.RestartIntegrationServer(ctx, deploymentID); err != nil { + return fmt.Errorf("cannot restart integrations server: %w", err) + } + + return nil +} diff --git a/functionaltests/internal/terraform/logger.go b/functionaltests/internal/terraform/logger.go new file mode 100644 index 00000000000..c5f56005b12 --- /dev/null +++ b/functionaltests/internal/terraform/logger.go @@ -0,0 +1,33 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package terraform + +import ( + "testing" +) + +// tfLoggerv2 wraps a testing.TB to implement the printfer interface +// required by terraform-exec logger. +type tfLoggerv2 struct { + testing.TB +} + +// Printf implements terraform-exec.printfer interface +func (l *tfLoggerv2) Printf(format string, v ...interface{}) { + l.Logf(format, v...) +} diff --git a/functionaltests/internal/terraform/runner.go b/functionaltests/internal/terraform/runner.go new file mode 100644 index 00000000000..9a4dae27f6d --- /dev/null +++ b/functionaltests/internal/terraform/runner.go @@ -0,0 +1,95 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package terraform + +import ( + "context" + "encoding/json" + "fmt" + "testing" + + "github.com/hashicorp/terraform-exec/tfexec" +) + +type Runner struct { + initialized bool + outputs map[string]tfexec.OutputMeta + tf *tfexec.Terraform +} + +func New(t *testing.T, workingDir string) (*Runner, error) { + tr := Runner{} + + tf, err := tfexec.NewTerraform(workingDir, "terraform") + if err != nil { + return &tr, fmt.Errorf("error instantiating terraform runner: %w", err) + } + tf.SetLogger(&tfLoggerv2{t}) + tr.tf = tf + if err := tr.init(); err != nil { + return &tr, fmt.Errorf("cannot run terraform init: %w", err) + } else { + tr.initialized = true + } + + return &tr, nil +} + +func (t *Runner) init() error { + return t.tf.Init(context.Background(), tfexec.Upgrade(true)) +} + +func (t *Runner) Apply(ctx context.Context, vars ...tfexec.ApplyOption) error { + if !t.initialized { + if err := t.init(); err != nil { + return fmt.Errorf("cannot init before apply: %w", err) + } + } + if err := t.tf.Apply(ctx, vars...); err != nil { + return fmt.Errorf("cannot apply: %w", err) + } + + output, err := t.tf.Output(ctx) + if err != nil { + return fmt.Errorf("cannot run terraform output: %w", err) + } + + t.outputs = output + return nil +} + +func (t *Runner) Destroy(ctx context.Context, vars ...tfexec.DestroyOption) error { + if !t.initialized { + if err := t.init(); err != nil { + return fmt.Errorf("cannot init before apply: %w", err) + } + } + + return t.tf.Destroy(ctx, vars...) +} + +func (t *Runner) Output(name string, res any) error { + o, ok := t.outputs[name] + if !ok { + return fmt.Errorf("output named %s not found", name) + } + if err := json.Unmarshal(o.Value, res); err != nil { + return fmt.Errorf("cannot unmarshal output: %w", err) + } + return nil +} diff --git a/internal/glog/glog.go b/functionaltests/internal/terraform/var.go similarity index 74% rename from internal/glog/glog.go rename to functionaltests/internal/terraform/var.go index c7f62eecf96..a31c94f6963 100644 --- a/internal/glog/glog.go +++ b/functionaltests/internal/terraform/var.go @@ -15,14 +15,15 @@ // specific language governing permissions and limitations // under the License. -package glog +package terraform -import "log" +import ( + "fmt" -func Fatal(args ...interface{}) { - log.Fatal(args...) -} + "github.com/hashicorp/terraform-exec/tfexec" +) -func Fatalf(format string, args ...interface{}) { - log.Fatalf(format, args...) +// Var is a helper to simplify creating Terraform vars to pass to terraform-exec. +func Var(name, value string) *tfexec.VarOption { + return tfexec.Var(fmt.Sprintf("%s=%s", name, value)) } diff --git a/functionaltests/main_test.go b/functionaltests/main_test.go new file mode 100644 index 00000000000..151a3b83d38 --- /dev/null +++ b/functionaltests/main_test.go @@ -0,0 +1,136 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package functionaltests + +import ( + "context" + "flag" + "fmt" + "testing" + + "github.com/elastic/apm-server/functionaltests/internal/esclient" + "github.com/elastic/go-elasticsearch/v8/typedapi/types" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +var cleanupOnFailure *bool = flag.Bool("cleanup-on-failure", true, "Whether to run cleanup even if the test failed.") + +// target is the Elastic Cloud environment to target with these test. +// We use 'pro' for production as that is the key used to retrieve EC_API_KEY from secret storage. +var target *string = flag.String("target", "pro", "The target environment where to run tests againts. Valid values are: qa, pro") + +// expectedIngestForASingleRun() represent the expected number of ingested document after a +// single run of ingest(). +// Only non aggregation data streams are included, as aggregation ones differs on different +// runs. +func expectedIngestForASingleRun() esclient.APMDataStreamsDocCount { + return map[string]int{ + "traces-apm-default": 15013, + "metrics-apm.app.opbeans_python-default": 1437, + "metrics-apm.internal-default": 1351, + "logs-apm.error-default": 364, + } +} + +// getDocsCountPerDS retrieves document count. +func getDocsCountPerDS(t *testing.T, ctx context.Context, ecc *esclient.Client) (esclient.APMDataStreamsDocCount, error) { + t.Helper() + return ecc.ApmDocCount(ctx) +} + +// assertDocCount check if specified document count is equal to expected minus +// documents count from a previous state. +func assertDocCount(t *testing.T, docsCount, previous, expected esclient.APMDataStreamsDocCount) { + t.Helper() + for ds, v := range docsCount { + if e, ok := expected[ds]; ok { + assert.Equal(t, e, v-previous[ds], + fmt.Sprintf("wrong document count for %s", ds)) + } + } +} + +type checkDatastreamWant struct { + Quantity int + DSManagedBy string + IndicesPerDs int + PreferIlm bool + IndicesManagedBy []string +} + +// assertDatastreams assert expected values on specific data streams in a cluster. +func assertDatastreams(t *testing.T, expected checkDatastreamWant, actual []types.DataStream) { + t.Helper() + + require.Len(t, actual, expected.Quantity, "number of APM datastream differs from expectations") + for _, v := range actual { + if expected.PreferIlm { + assert.True(t, v.PreferIlm, "datastream %s should prefer ILM", v.Name) + } else { + assert.False(t, v.PreferIlm, "datastream %s should not prefer ILM", v.Name) + } + + assert.Equal(t, expected.DSManagedBy, v.NextGenerationManagedBy.Name, + `datastream %s should be managed by "%s"`, v.Name, expected.DSManagedBy, + ) + assert.Len(t, v.Indices, expected.IndicesPerDs, + "datastream %s should have %d indices", v.Name, expected.IndicesPerDs, + ) + for i, index := range v.Indices { + assert.Equal(t, expected.IndicesManagedBy[i], index.ManagedBy.Name, + `index %s should be managed by "%s"`, index.IndexName, + expected.IndicesManagedBy[i], + ) + } + } + +} + +const ( + targetQA = "qa" + // we use 'pro' because is the target passed by the Buildkite pipeline running + // these tests. + targetProd = "pro" +) + +// regionFrom returns the appropriate region to run test +// againts based on specified target. +// https://www.elastic.co/guide/en/cloud/current/ec-regions-templates-instances.html +func regionFrom(target string) string { + switch target { + case targetQA: + return "aws-eu-west-1" + case targetProd: + return "eu-west-1" + default: + panic("target value is not accepted") + } +} + +func endpointFrom(target string) string { + switch target { + case targetQA: + return "https://public-api.qa.cld.elstc.co" + case targetProd: + return "https://api.elastic-cloud.com" + default: + panic("target value is not accepted") + } +} diff --git a/functionaltests/utils_test.go b/functionaltests/utils_test.go new file mode 100644 index 00000000000..83f5086331f --- /dev/null +++ b/functionaltests/utils_test.go @@ -0,0 +1,37 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package functionaltests + +import ( + "os" + "testing" + + "github.com/stretchr/testify/require" +) + +// ecAPICheck verifies if EC_API_KEY env var is set. +// This is a simple check to alert users if this necessary env var +// is not available. +// +// Functional tests are expected to run Terraform code to operate +// on infrastructure required for each tests and to query Elastic +// Cloud APIs. In both cases a valid API key is required. +func ecAPICheck(t *testing.T) { + t.Helper() + require.NotEmpty(t, os.Getenv("EC_API_KEY"), "EC_API_KEY env var not set") +} diff --git a/go.mk b/go.mk index a4c8491f739..90cbc9485d4 100644 --- a/go.mk +++ b/go.mk @@ -8,5 +8,11 @@ GITROOT ?= $(shell git rev-parse --show-toplevel) GOLANG_VERSION=$(shell cat $(GITROOT)/.go-version) GOARCH:=$(shell go env GOARCH) -APM_SERVER_VERSION=$(shell grep "const Version" $(GITROOT)/internal/version/version.go | cut -d'=' -f2 | tr -d '" ') +APM_SERVER_ONLY_VERSION=$(shell grep "const Version" $(GITROOT)/internal/version/version.go | cut -d'=' -f2 | tr -d '" ') +# DRA uses a qualifier to annotate the type of release (alpha, rc, etc) +ifdef ELASTIC_QUALIFIER + APM_SERVER_VERSION=$(APM_SERVER_ONLY_VERSION)-$(ELASTIC_QUALIFIER) +else + APM_SERVER_VERSION=$(APM_SERVER_ONLY_VERSION) +endif APM_SERVER_VERSION_MAJORMINOR=$(shell echo $(APM_SERVER_VERSION) | sed 's/\(.*\..*\)\..*/\1/') diff --git a/go.mod b/go.mod index fd9043f0fae..7c5ce74a349 100644 --- a/go.mod +++ b/go.mod @@ -3,120 +3,115 @@ module github.com/elastic/apm-server go 1.23.0 require ( + github.com/KimMachineGun/automemlimit v0.7.0 github.com/cespare/xxhash/v2 v2.3.0 - github.com/dgraph-io/badger/v2 v2.2007.4 + github.com/cockroachdb/pebble/v2 v2.0.2 github.com/dustin/go-humanize v1.0.1 - github.com/elastic/apm-aggregation v1.1.0 - github.com/elastic/apm-data v1.13.1 - github.com/elastic/beats/v7 v7.0.0-alpha2.0.20240823193033-af33fad4d50b - github.com/elastic/elastic-agent-client/v7 v7.16.0 - github.com/elastic/elastic-agent-libs v0.12.1 - github.com/elastic/elastic-agent-system-metrics v0.11.3 + github.com/elastic/apm-aggregation v1.2.0 + github.com/elastic/apm-data v1.16.0 + github.com/elastic/beats/v7 v7.0.0-alpha2.0.20241231140711-7806f1a2cb26 + github.com/elastic/elastic-agent-client/v7 v7.17.0 + github.com/elastic/elastic-agent-libs v0.18.3 + github.com/elastic/elastic-agent-system-metrics v0.11.7 github.com/elastic/gmux v0.3.2 - github.com/elastic/go-docappender/v2 v2.3.0 - github.com/elastic/go-elasticsearch/v8 v8.15.0 - github.com/elastic/go-sysinfo v1.14.2 + github.com/elastic/go-docappender/v2 v2.4.0 + github.com/elastic/go-elasticsearch/v8 v8.17.0 + github.com/elastic/go-sysinfo v1.15.0 github.com/elastic/go-ucfg v0.8.8 github.com/go-sourcemap/sourcemap v2.1.4+incompatible github.com/gofrs/flock v0.12.1 - github.com/gofrs/uuid v4.4.0+incompatible + github.com/gofrs/uuid/v5 v5.3.0 github.com/gogo/protobuf v1.3.2 github.com/google/go-cmp v0.6.0 github.com/gorilla/mux v1.8.1 github.com/hashicorp/golang-lru v1.0.2 - github.com/jaegertracing/jaeger v1.60.0 + github.com/joeshaw/multierror v0.0.0-20140124173710-69b34d4ec901 github.com/libp2p/go-reuseport v0.4.0 github.com/modern-go/reflect2 v1.0.2 - github.com/open-telemetry/opentelemetry-collector-contrib/pkg/translator/jaeger v0.109.0 github.com/patrickmn/go-cache v2.1.0+incompatible github.com/pkg/errors v0.9.1 github.com/ryanuber/go-glob v1.0.0 github.com/spf13/cobra v1.8.1 github.com/spf13/pflag v1.0.5 - github.com/stretchr/testify v1.9.0 - go.elastic.co/apm/module/apmelasticsearch/v2 v2.6.2 - go.elastic.co/apm/module/apmgorilla/v2 v2.6.2 - go.elastic.co/apm/module/apmgrpc/v2 v2.6.2 - go.elastic.co/apm/module/apmhttp/v2 v2.6.2 - go.elastic.co/apm/module/apmotel/v2 v2.6.2 - go.elastic.co/apm/v2 v2.6.2 + github.com/stretchr/testify v1.10.0 + go.elastic.co/apm/module/apmelasticsearch/v2 v2.6.3 + go.elastic.co/apm/module/apmgorilla/v2 v2.6.3 + go.elastic.co/apm/module/apmgrpc/v2 v2.6.3 + go.elastic.co/apm/module/apmhttp/v2 v2.6.3 + go.elastic.co/apm/module/apmotel/v2 v2.6.3 + go.elastic.co/apm/v2 v2.6.3 go.elastic.co/fastjson v1.4.0 - go.opentelemetry.io/collector/consumer v0.109.0 - go.opentelemetry.io/collector/pdata v1.15.0 - go.opentelemetry.io/otel v1.30.0 - go.opentelemetry.io/otel/metric v1.30.0 - go.opentelemetry.io/otel/sdk/metric v1.30.0 + go.opentelemetry.io/collector/pdata v1.24.0 + go.opentelemetry.io/otel v1.34.0 + go.opentelemetry.io/otel/metric v1.34.0 + go.opentelemetry.io/otel/sdk/metric v1.34.0 go.uber.org/automaxprocs v1.6.0 go.uber.org/zap v1.27.0 - golang.org/x/net v0.30.0 - golang.org/x/sync v0.8.0 - golang.org/x/term v0.25.0 - golang.org/x/time v0.7.0 - google.golang.org/grpc v1.67.1 - google.golang.org/protobuf v1.35.1 + go.uber.org/zap/exp v0.3.0 + golang.org/x/net v0.34.0 + golang.org/x/sync v0.10.0 + golang.org/x/term v0.28.0 + golang.org/x/time v0.9.0 + google.golang.org/grpc v1.70.0 + google.golang.org/protobuf v1.36.4 gopkg.in/yaml.v3 v3.0.1 ) require ( - github.com/DataDog/zstd v1.4.5 // indirect + github.com/DataDog/zstd v1.5.6 // indirect github.com/Microsoft/go-winio v0.6.2 // indirect - github.com/OneOfOne/xxhash v1.2.8 // indirect - github.com/Shopify/sarama v1.38.1 // indirect - github.com/apache/thrift v0.20.0 // indirect github.com/armon/go-radix v1.0.0 // indirect github.com/axiomhq/hyperloglog v0.2.0 // indirect github.com/beorn7/perks v1.0.1 // indirect - github.com/cespare/xxhash v1.1.0 // indirect + github.com/cockroachdb/crlib v0.0.0-20241015224233-894974b3ad94 // indirect github.com/cockroachdb/errors v1.11.3 // indirect - github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce // indirect + github.com/cockroachdb/fifo v0.0.0-20240816210425-c5d0cb0b6fc0 // indirect github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect github.com/cockroachdb/pebble v1.1.2 // indirect github.com/cockroachdb/redact v1.1.5 // indirect + github.com/cockroachdb/swiss v0.0.0-20240612210725-f4de07ae6964 // indirect github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect - github.com/containerd/errdefs v0.1.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/dgraph-io/ristretto v0.1.1 // indirect - github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 // indirect - github.com/dgryski/go-metro v0.0.0-20180109044635-280f6062b5bc // indirect + github.com/dgryski/go-metro v0.0.0-20211217172704-adc40b04c140 // indirect github.com/dlclark/regexp2 v1.8.1 // indirect - github.com/docker/distribution v2.8.3+incompatible // indirect + github.com/docker/go-connections v0.5.0 // indirect github.com/dop251/goja v0.0.0-20230427124612-428fc442ff5f // indirect - github.com/dop251/goja_nodejs v0.0.0-20230322100729-2550c7b6c124 // indirect - github.com/eapache/go-resiliency v1.6.0 // indirect + github.com/dop251/goja_nodejs v0.0.0-20171011081505-adff31b136e6 // indirect + github.com/eapache/go-resiliency v1.7.0 // indirect github.com/eapache/go-xerial-snappy v0.0.0-20230731223053-c322873962e3 // indirect github.com/eapache/queue v1.1.0 // indirect + github.com/ebitengine/purego v0.8.0 // indirect github.com/elastic/elastic-transport-go/v8 v8.6.0 // indirect github.com/elastic/go-lumber v0.1.2-0.20220819171948-335fde24ea0f // indirect github.com/elastic/go-structform v0.0.10 // indirect github.com/elastic/go-windows v1.0.2 // indirect github.com/elastic/gosigar v0.14.3 // indirect - github.com/elastic/opentelemetry-lib v0.9.0 // indirect + github.com/elastic/opentelemetry-lib v0.14.0 // indirect github.com/elastic/pkcs8 v1.0.0 // indirect + github.com/elastic/sarama v1.19.1-0.20241120141909-c7eabfcee7e5 // indirect github.com/fatih/color v1.16.0 // indirect - github.com/frankban/quicktest v1.14.0 // indirect - github.com/getsentry/sentry-go v0.27.0 // indirect + github.com/getsentry/sentry-go v0.29.1 // indirect github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-ole/go-ole v1.2.6 // indirect - github.com/gofrs/uuid/v5 v5.2.0 // indirect - github.com/gogo/googleapis v1.4.1 // indirect - github.com/golang/glog v1.2.2 // indirect github.com/golang/protobuf v1.5.4 // indirect - github.com/golang/snappy v0.0.4 // indirect + github.com/golang/snappy v0.0.5-0.20231225225746-43d5d4cd4e0e // indirect github.com/gomodule/redigo v1.8.9 // indirect github.com/google/uuid v1.6.0 // indirect + github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect github.com/h2non/filetype v1.1.3 // indirect + github.com/hashicorp/errwrap v1.1.0 // indirect + github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/go-uuid v1.0.3 // indirect - github.com/imdario/mergo v0.3.13 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/jcmturner/aescts/v2 v2.0.0 // indirect github.com/jcmturner/dnsutils/v2 v2.0.0 // indirect github.com/jcmturner/gofork v1.7.6 // indirect + github.com/jcmturner/goidentity/v6 v6.0.1 // indirect github.com/jcmturner/gokrb5/v8 v8.4.4 // indirect github.com/jcmturner/rpc/v2 v2.0.3 // indirect - github.com/joeshaw/multierror v0.0.0-20140124173710-69b34d4ec901 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/klauspost/compress v1.17.9 // indirect + github.com/klauspost/compress v1.17.11 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect github.com/lufia/plan9stats v0.0.0-20220913051719-115f729f3c8c // indirect @@ -125,21 +120,18 @@ require ( github.com/mitchellh/hashstructure v1.1.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect - github.com/open-telemetry/opentelemetry-collector-contrib/internal/coreinternal v0.109.0 // indirect - github.com/pierrec/lz4 v2.6.1+incompatible // indirect + github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // indirect github.com/pierrec/lz4/v4 v4.1.21 // indirect github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/power-devops/perfstat v0.0.0-20220216144756-c35f1ee13d7c // indirect - github.com/prometheus/client_golang v1.20.2 // indirect + github.com/prometheus/client_golang v1.20.5 // indirect github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.57.0 // indirect + github.com/prometheus/common v0.60.1 // indirect github.com/prometheus/procfs v0.15.1 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect - github.com/rogpeppe/go-internal v1.12.0 // indirect - github.com/shirou/gopsutil/v3 v3.24.5 // indirect - github.com/shirou/gopsutil/v4 v4.24.7 // indirect - github.com/shoenig/go-m1cpu v0.1.6 // indirect + github.com/rogpeppe/go-internal v1.13.1 // indirect + github.com/shirou/gopsutil/v4 v4.24.9 // indirect github.com/tklauser/go-sysconf v0.3.12 // indirect github.com/tklauser/numcpus v0.6.1 // indirect github.com/xdg-go/pbkdf2 v1.0.0 // indirect @@ -147,33 +139,21 @@ require ( github.com/xdg-go/stringprep v1.0.4 // indirect github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect github.com/yusufpapurcu/wmi v1.2.4 // indirect - go.elastic.co/apm/module/apmzap/v2 v2.6.0 // indirect + go.elastic.co/apm/module/apmzap/v2 v2.6.3 // indirect go.elastic.co/ecszap v1.0.2 // indirect - go.opentelemetry.io/collector/semconv v0.109.0 // indirect - go.opentelemetry.io/otel/sdk v1.30.0 // indirect - go.opentelemetry.io/otel/trace v1.30.0 // indirect + go.opentelemetry.io/auto/sdk v1.1.0 // indirect + go.opentelemetry.io/collector/consumer v1.22.0 // indirect + go.opentelemetry.io/collector/semconv v0.116.0 // indirect + go.opentelemetry.io/otel/sdk v1.34.0 // indirect + go.opentelemetry.io/otel/trace v1.34.0 // indirect go.uber.org/multierr v1.11.0 // indirect - golang.org/x/crypto v0.28.0 // indirect - golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 // indirect - golang.org/x/sys v0.26.0 // indirect - golang.org/x/text v0.19.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240822170219-fc7c04adadcd // indirect - gopkg.in/jcmturner/aescts.v1 v1.0.1 // indirect - gopkg.in/jcmturner/dnsutils.v1 v1.0.1 // indirect - gopkg.in/jcmturner/goidentity.v3 v3.0.0 // indirect - gopkg.in/jcmturner/gokrb5.v7 v7.5.0 // indirect - gopkg.in/jcmturner/rpc.v1 v1.1.0 // indirect + golang.org/x/crypto v0.32.0 // indirect + golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c // indirect + golang.org/x/sys v0.29.0 // indirect + golang.org/x/text v0.21.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20241209162323-e6fa225c2576 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect howett.net/plist v1.0.1 // indirect ) -replace ( - github.com/Shopify/sarama => github.com/elastic/sarama v1.19.1-0.20210823122811-11c3ef800752 - github.com/docker/docker => github.com/docker/engine v0.0.0-20191113042239-ea84732a7725 - github.com/docker/go-plugins-helpers => github.com/elastic/go-plugins-helpers v0.0.0-20200207104224-bdf17607b79f - github.com/dop251/goja => github.com/andrewkroh/goja v0.0.0-20190128172624-dd2ac4456e20 - github.com/dop251/goja_nodejs => github.com/dop251/goja_nodejs v0.0.0-20171011081505-adff31b136e6 // pin to version used by beats - // We replace golang/glog, which is used by ristretto, to avoid polluting the - // command line flags and conflicting with command line flags added by libbeat. - github.com/golang/glog => ./internal/glog -) +replace github.com/dop251/goja => github.com/elastic/goja v0.0.0-20190128172624-dd2ac4456e20 // pin to version used by beats diff --git a/go.sum b/go.sum index a714728b1be..b53c9a1de8b 100644 --- a/go.sum +++ b/go.sum @@ -1,188 +1,184 @@ -github.com/Azure/azure-sdk-for-go v65.0.0+incompatible h1:HzKLt3kIwMm4KeJYTdx9EbjRYTySD/t8i1Ee/W5EGXw= +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +github.com/Azure/azure-sdk-for-go v68.0.0+incompatible h1:fcYLmCpyNYRnvJbPerq7U0hS+6+I79yEDJBqVNcqUzU= github.com/Azure/azure-sdk-for-go/sdk/azcore v1.13.0 h1:GJHeeA2N7xrG3q30L2UXDyuWRzDM900/65j70wcM4Ww= github.com/Azure/azure-sdk-for-go/sdk/azcore v1.13.0/go.mod h1:l38EPgmsp71HHLq9j7De57JcKOWPyhrsW1Awm1JS6K0= github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.7.0 h1:tfLQ34V6F7tVSwoTf/4lH5sE0o6eCJuNDTmH09nDpbc= github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.7.0/go.mod h1:9kIvujWAA58nmPmWB1m23fyWic1kYZMxD9CxaWn4Qpg= github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0 h1:ywEEhmNahHBihViHepv3xPBn1663uRv2t2q/ESv9seY= github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0/go.mod h1:iZDifYGJTIgIIkYRNWPENUnqx6bJ2xnSDFI2tjwZNuY= -github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/containerservice/armcontainerservice/v4 v4.6.0 h1:AAIdAyPkFff6XTct2lQCxOWN/+LnA41S7kIkzKaMbyE= -github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/containerservice/armcontainerservice/v4 v4.6.0/go.mod h1:noQIdW75SiQFB3mSFJBr4iRRH83S9skaFiBv4C0uEs0= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/containerservice/armcontainerservice/v4 v4.8.0 h1:0nGmzwBv5ougvzfGPCO2ljFRHvun57KpNrVCMrlk0ns= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/containerservice/armcontainerservice/v4 v4.8.0/go.mod h1:gYq8wyDgv6JLhGbAU6gg8amCPgQWRE+aCvrV2gyzdfs= github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2 h1:XHOnouVk1mxXfQidrMEnLlPk9UMeRtyBTnEFtxkV0kU= github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/DataDog/zstd v1.4.5 h1:EndNeuB0l9syBZhut0wns3gV1hL8zX8LIu6ZiVHWLIQ= -github.com/DataDog/zstd v1.4.5/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= +github.com/DataDog/zstd v1.5.6 h1:LbEglqepa/ipmmQJUDnSsfvA8e8IStVcGaFWDuxvGOY= +github.com/DataDog/zstd v1.5.6/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= github.com/HdrHistogram/hdrhistogram-go v1.1.2 h1:5IcZpTvzydCQeHzK4Ef/D5rrSqwxob0t8PQPMybUNFM= github.com/HdrHistogram/hdrhistogram-go v1.1.2/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo= +github.com/IBM/sarama v1.43.3 h1:Yj6L2IaNvb2mRBop39N7mmJAHBVY3dTPncr3qGVkxPA= +github.com/IBM/sarama v1.43.3/go.mod h1:FVIRaLrhK3Cla/9FfRF5X9Zua2KpS3SYIXxhac1H+FQ= +github.com/KimMachineGun/automemlimit v0.7.0 h1:7G06p/dMSf7G8E6oq+f2uOPuVncFyIlDI/pBWK49u88= +github.com/KimMachineGun/automemlimit v0.7.0/go.mod h1:QZxpHaGOQoYvFhv/r4u3U0JTC2ZcOwbSr11UZF46UBM= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= -github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= -github.com/OneOfOne/xxhash v1.2.8 h1:31czK/TI9sNkxIKfaUfGlU47BAxQ0ztGgd9vPyqimf8= -github.com/OneOfOne/xxhash v1.2.8/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q= -github.com/Shopify/toxiproxy v2.1.4+incompatible h1:TKdv8HiTLgE5wdJuEML90aBgNWsokNbMijUGhmcoBJc= -github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= -github.com/andrewkroh/goja v0.0.0-20190128172624-dd2ac4456e20 h1:7rj9qZ63knnVo2ZeepYHvHuRdG76f3tRUTdIQDzRBeI= -github.com/andrewkroh/goja v0.0.0-20190128172624-dd2ac4456e20/go.mod h1:cI59GRkC2FRaFYtgbYEqMlgnnfvAwXzjojyZKXwklNg= -github.com/apache/thrift v0.20.0 h1:631+KvYbsBZxmuJjYwhezVsrfc/TbqtZV4QcxOX1fOI= -github.com/apache/thrift v0.20.0/go.mod h1:hOk1BQqcp2OLzGsyVXdfMk7YFlMxK3aoEVhjD06QhB8= -github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= +github.com/aclements/go-perfevent v0.0.0-20240301234650-f7843625020f h1:JjxwchlOepwsUWcQwD2mLUAGE9aCp0/ehy6yCHFBOvo= +github.com/aclements/go-perfevent v0.0.0-20240301234650-f7843625020f/go.mod h1:tMDTce/yLLN/SK8gMOxQfnyeMeCg8KGzp0D1cbECEeo= github.com/armon/go-radix v1.0.0 h1:F4z6KzEeeQIMeLFa97iZU6vupzoecKdU5TX24SNppXI= github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= -github.com/aws/aws-sdk-go-v2 v1.30.4 h1:frhcagrVNrzmT95RJImMHgabt99vkXGslubDaDagTk8= -github.com/aws/aws-sdk-go-v2 v1.30.4/go.mod h1:CT+ZPWXbYrci8chcARI3OmI/qgd+f6WtuLOoaIA8PR0= -github.com/aws/aws-sdk-go-v2/config v1.27.29 h1:+ZPKb3u9Up4KZWLGTtpTmC5T3XmRD1ZQ8XQjRCHUvJw= -github.com/aws/aws-sdk-go-v2/config v1.27.29/go.mod h1:yxqvuubha9Vw8stEgNiStO+yZpP68Wm9hLmcm+R/Qk4= -github.com/aws/aws-sdk-go-v2/credentials v1.17.29 h1:CwGsupsXIlAFYuDVHv1nnK0wnxO0wZ/g1L8DSK/xiIw= -github.com/aws/aws-sdk-go-v2/credentials v1.17.29/go.mod h1:BPJ/yXV92ZVq6G8uYvbU0gSl8q94UB63nMT5ctNO38g= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.12 h1:yjwoSyDZF8Jth+mUk5lSPJCkMC0lMy6FaCD51jm6ayE= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.12/go.mod h1:fuR57fAgMk7ot3WcNQfb6rSEn+SUffl7ri+aa8uKysI= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.16 h1:TNyt/+X43KJ9IJJMjKfa3bNTiZbUP7DeCxfbTROESwY= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.16/go.mod h1:2DwJF39FlNAUiX5pAc0UNeiz16lK2t7IaFcm0LFHEgc= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.16 h1:jYfy8UPmd+6kJW5YhY0L1/KftReOGxI/4NtVSTh9O/I= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.16/go.mod h1:7ZfEPZxkW42Afq4uQB8H2E2e6ebh6mXTueEpYzjCzcs= +github.com/aws/aws-sdk-go-v2 v1.32.7 h1:ky5o35oENWi0JYWUZkB7WYvVPP+bcRF5/Iq7JWSb5Rw= +github.com/aws/aws-sdk-go-v2 v1.32.7/go.mod h1:P5WJBrYqqbWVaOxgH0X/FYYD47/nooaPOZPlQdmiN2U= +github.com/aws/aws-sdk-go-v2/config v1.28.7 h1:GduUnoTXlhkgnxTD93g1nv4tVPILbdNQOzav+Wpg7AE= +github.com/aws/aws-sdk-go-v2/config v1.28.7/go.mod h1:vZGX6GVkIE8uECSUHB6MWAUsd4ZcG2Yq/dMa4refR3M= +github.com/aws/aws-sdk-go-v2/credentials v1.17.48 h1:IYdLD1qTJ0zanRavulofmqut4afs45mOWEI+MzZtTfQ= +github.com/aws/aws-sdk-go-v2/credentials v1.17.48/go.mod h1:tOscxHN3CGmuX9idQ3+qbkzrjVIx32lqDSU1/0d/qXs= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.22 h1:kqOrpojG71DxJm/KDPO+Z/y1phm1JlC8/iT+5XRmAn8= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.22/go.mod h1:NtSFajXVVL8TA2QNngagVZmUtXciyrHOt7xgz4faS/M= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.26 h1:I/5wmGMffY4happ8NOCuIUEWGUvvFp5NSeQcXl9RHcI= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.26/go.mod h1:FR8f4turZtNy6baO0KJ5FJUmXH/cSkI9fOngs0yl6mA= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.26 h1:zXFLuEuMMUOvEARXFUVJdfqZ4bvvSgdGRq/ATcrQxzM= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.26/go.mod h1:3o2Wpy0bogG1kyOPrgkXA8pgIfEEv0+m19O9D5+W8y8= github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 h1:VaRN3TlFdd6KxX1x3ILT5ynH6HvKgqdiXoTxAF4HQcQ= github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1/go.mod h1:FbtygfRFze9usAadmnGJNc8KsP346kEe+y2/oyhGAGc= -github.com/aws/aws-sdk-go-v2/service/ec2 v1.176.0 h1:fWhkSvaQqa5eWiRwBw10FUnk1YatAQ9We4GdGxKiCtg= -github.com/aws/aws-sdk-go-v2/service/ec2 v1.176.0/go.mod h1:ISODge3zgdwOEa4Ou6WM9PKbxJWJ15DYKnr2bfmCAIA= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.4 h1:KypMCbLPPHEmf9DgMGw51jMj77VfGPAN2Kv4cfhlfgI= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.4/go.mod h1:Vz1JQXliGcQktFTN/LN6uGppAIRoLBR2bMvIMP0gOjc= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.18 h1:tJ5RnkHCiSH0jyd6gROjlJtNwov0eGYNz8s8nFcR0jQ= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.18/go.mod h1:++NHzT+nAF7ZPrHPsA+ENvsXkOO8wEu+C6RXltAG4/c= -github.com/aws/aws-sdk-go-v2/service/sso v1.22.5 h1:zCsFCKvbj25i7p1u94imVoO447I/sFv8qq+lGJhRN0c= -github.com/aws/aws-sdk-go-v2/service/sso v1.22.5/go.mod h1:ZeDX1SnKsVlejeuz41GiajjZpRSWR7/42q/EyA/QEiM= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.5 h1:SKvPgvdvmiTWoi0GAJ7AsJfOz3ngVkD/ERbs5pUnHNI= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.5/go.mod h1:20sz31hv/WsPa3HhU3hfrIet2kxM4Pe0r20eBZ20Tac= -github.com/aws/aws-sdk-go-v2/service/sts v1.30.5 h1:OMsEmCyz2i89XwRwPouAJvhj81wINh+4UK+k/0Yo/q8= -github.com/aws/aws-sdk-go-v2/service/sts v1.30.5/go.mod h1:vmSqFK+BVIwVpDAGZB3CoCXHzurt4qBE8lf+I/kRTh0= -github.com/aws/smithy-go v1.20.4 h1:2HK1zBdPgRbjFOHlfeQZfpC4r72MOb9bZkiFwggKO+4= -github.com/aws/smithy-go v1.20.4/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg= +github.com/aws/aws-sdk-go-v2/service/ec2 v1.198.1 h1:YbNopxjd9baM83YEEmkaYHi+NuJt0AszeaSLqo0CVr0= +github.com/aws/aws-sdk-go-v2/service/ec2 v1.198.1/go.mod h1:mwr3iRm8u1+kkEx4ftDM2Q6Yr0XQFBKrP036ng+k5Lk= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.1 h1:iXtILhvDxB6kPvEXgsDhGaZCSC6LQET5ZHSdJozeI0Y= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.1/go.mod h1:9nu0fVANtYiAePIBh2/pFUSwtJ402hLnp854CNoDOeE= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.7 h1:8eUsivBQzZHqe/3FE+cqwfH+0p5Jo8PFM/QYQSmeZ+M= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.7/go.mod h1:kLPQvGUmxn/fqiCrDeohwG33bq2pQpGeY62yRO6Nrh0= +github.com/aws/aws-sdk-go-v2/service/sso v1.24.8 h1:CvuUmnXI7ebaUAhbJcDy9YQx8wHR69eZ9I7q5hszt/g= +github.com/aws/aws-sdk-go-v2/service/sso v1.24.8/go.mod h1:XDeGv1opzwm8ubxddF0cgqkZWsyOtw4lr6dxwmb6YQg= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.7 h1:F2rBfNAL5UyswqoeWv9zs74N/NanhK16ydHW1pahX6E= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.7/go.mod h1:JfyQ0g2JG8+Krq0EuZNnRwX0mU0HrwY/tG6JNfcqh4k= +github.com/aws/aws-sdk-go-v2/service/sts v1.33.3 h1:Xgv/hyNgvLda/M9l9qxXc4UFSgppnRczLxlMs5Ae/QY= +github.com/aws/aws-sdk-go-v2/service/sts v1.33.3/go.mod h1:5Gn+d+VaaRgsjewpMvGazt0WfcFO+Md4wLOuBfGR9Bc= +github.com/aws/smithy-go v1.22.1 h1:/HPHZQ0g7f4eUeK6HKglFz8uwVfZKgoI25rb/J+dnro= +github.com/aws/smithy-go v1.22.1/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg= github.com/axiomhq/hyperloglog v0.2.0 h1:u1XT3yyY1rjzlWuP6NQIrV4bRYHOaqZaovqjcBEvZJo= github.com/axiomhq/hyperloglog v0.2.0/go.mod h1:GcgMjz9gaDKZ3G0UMS6Fq/VkZ4l7uGgcJyxA7M+omIM= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= -github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= -github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f h1:otljaYPt5hWxV3MUfO5dFPFiOXg9CyG5/kCfayTqsJ4= -github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cockroachdb/crlib v0.0.0-20241015224233-894974b3ad94 h1:bvJv505UUfjzbaIPdNS4AEkHreDqQk6yuNpsdRHpwFA= +github.com/cockroachdb/crlib v0.0.0-20241015224233-894974b3ad94/go.mod h1:Gq51ZeKaFCXk6QwuGM0w1dnaOqc/F5zKT2zA9D6Xeac= +github.com/cockroachdb/datadriven v1.0.3-0.20240530155848-7682d40af056 h1:slXychO2uDM6hYRu4c0pD0udNI8uObfeKN6UInWViS8= +github.com/cockroachdb/datadriven v1.0.3-0.20240530155848-7682d40af056/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU= github.com/cockroachdb/errors v1.11.3 h1:5bA+k2Y6r+oz/6Z/RFlNeVCesGARKuC6YymtcDrbC/I= github.com/cockroachdb/errors v1.11.3/go.mod h1:m4UIW4CDjx+R5cybPsNrRbreomiFqt8o1h1wUVazSd8= -github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce h1:giXvy4KSc/6g/esnpM7Geqxka4WSqI1SZc7sMJFd3y4= -github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce/go.mod h1:9/y3cnZ5GKakj/H4y9r9GTjCvAFta7KLgSHPJJYc52M= +github.com/cockroachdb/fifo v0.0.0-20240816210425-c5d0cb0b6fc0 h1:pU88SPhIFid6/k0egdR5V6eALQYq2qbSmukrkgIh/0A= +github.com/cockroachdb/fifo v0.0.0-20240816210425-c5d0cb0b6fc0/go.mod h1:9/y3cnZ5GKakj/H4y9r9GTjCvAFta7KLgSHPJJYc52M= github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b h1:r6VH0faHjZeQy818SGhaone5OnYfxFR/+AzdY3sf5aE= github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs= +github.com/cockroachdb/metamorphic v0.0.0-20231108215700-4ba948b56895 h1:XANOgPYtvELQ/h4IrmPAohXqe2pWA8Bwhejr3VQoZsA= +github.com/cockroachdb/metamorphic v0.0.0-20231108215700-4ba948b56895/go.mod h1:aPd7gM9ov9M8v32Yy5NJrDyOcD8z642dqs+F0CeNXfA= github.com/cockroachdb/pebble v1.1.2 h1:CUh2IPtR4swHlEj48Rhfzw6l/d0qA31fItcIszQVIsA= github.com/cockroachdb/pebble v1.1.2/go.mod h1:4exszw1r40423ZsmkG/09AFEG83I0uDgfujJdbL6kYU= +github.com/cockroachdb/pebble/v2 v2.0.2 h1:PmmN7V/rDK+xgp5HiPV9e7ycAalyMjKwSIrcj/4HQz4= +github.com/cockroachdb/pebble/v2 v2.0.2/go.mod h1:NgxgNcWwyG/uxkLUZGM2aelshaLIZvc0hCX7SCfaO8s= github.com/cockroachdb/redact v1.1.5 h1:u1PMllDkdFfPWaNGMyLD1+so+aq3uUItthCFqzwPJ30= github.com/cockroachdb/redact v1.1.5/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= +github.com/cockroachdb/swiss v0.0.0-20240612210725-f4de07ae6964 h1:Ew0znI2JatzKy52N1iS5muUsHkf2UJuhocH7uFW7jjs= +github.com/cockroachdb/swiss v0.0.0-20240612210725-f4de07ae6964/go.mod h1:yBRu/cnL4ks9bgy4vAASdjIW+/xMlFwuHKqtmh3GZQg= github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 h1:zuQyyAKVxetITBuuhv3BI9cMrmStnpT18zmgmTxunpo= github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06/go.mod h1:7nc4anLGjupUW/PeY5qiNYsdNXj7zopG+eqsS7To5IQ= -github.com/containerd/containerd v1.7.20 h1:Sl6jQYk3TRavaU83h66QMbI2Nqg9Jm6qzwX57Vsn1SQ= -github.com/containerd/containerd v1.7.20/go.mod h1:52GsS5CwquuqPuLncsXwG0t2CiUce+KsNHJZQJvAgR0= -github.com/containerd/errdefs v0.1.0 h1:m0wCRBiu1WJT/Fr+iOoQHMQS/eP5myQ8lCv4Dz5ZURM= -github.com/containerd/errdefs v0.1.0/go.mod h1:YgWiiHtLmSeBrvpw+UfPijzbLaB77mEG1WwJTDETIV0= -github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= -github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= -github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dgraph-io/badger/v2 v2.2007.4 h1:TRWBQg8UrlUhaFdco01nO2uXwzKS7zd+HVdwV/GHc4o= -github.com/dgraph-io/badger/v2 v2.2007.4/go.mod h1:vSw/ax2qojzbN6eXHIx6KPKtCSHJN/Uz0X0VPruTIhk= -github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= -github.com/dgraph-io/ristretto v0.1.1 h1:6CWw5tJNgpegArSHpNHJKldNeq03FQCwYvfMVWajOK8= -github.com/dgraph-io/ristretto v0.1.1/go.mod h1:S1GPSBCYCIhmVNfcth17y2zZtQT6wzkzgwUve0VDWWA= -github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= -github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 h1:fAjc9m62+UWV/WAFKLNi6ZS0675eEUC9y3AlwSbQu1Y= -github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= -github.com/dgryski/go-metro v0.0.0-20180109044635-280f6062b5bc h1:8WFBn63wegobsYAX0YjD+8suexZDga5CctH4CCTx2+8= -github.com/dgryski/go-metro v0.0.0-20180109044635-280f6062b5bc/go.mod h1:c9O8+fpSOX1DM8cPNSkX/qsBWdkD4yd2dpciOWQjpBw= +github.com/dgryski/go-metro v0.0.0-20211217172704-adc40b04c140 h1:y7y0Oa6UawqTFPCDw9JG6pdKt4F9pAhHv0B7FMGaGD0= +github.com/dgryski/go-metro v0.0.0-20211217172704-adc40b04c140/go.mod h1:c9O8+fpSOX1DM8cPNSkX/qsBWdkD4yd2dpciOWQjpBw= github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= github.com/dlclark/regexp2 v1.8.1 h1:6Lcdwya6GjPUNsBct8Lg/yRPwMhABj269AAzdGSiR+0= github.com/dlclark/regexp2 v1.8.1/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= -github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk= -github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/engine v0.0.0-20191113042239-ea84732a7725 h1:j0zqmciWFnhB01BT/CyfoXNEONoxerGjkcxM8i6tlXI= -github.com/docker/engine v0.0.0-20191113042239-ea84732a7725/go.mod h1:3CPr2caMgTHxxIAZgEMd3uLYPDlRvPqCpyeRf6ncPcY= +github.com/docker/docker v27.3.1+incompatible h1:KttF0XoteNTicmUtBO0L2tP+J7FGRFTjaEF4k6WdhfI= +github.com/docker/docker v27.3.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c= github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/dop251/goja_nodejs v0.0.0-20171011081505-adff31b136e6 h1:RrkoB0pT3gnjXhL/t10BSP1mcr/0Ldea2uMyuBr2SWk= github.com/dop251/goja_nodejs v0.0.0-20171011081505-adff31b136e6/go.mod h1:hn7BA7c8pLvoGndExHudxTDKZ84Pyvv+90pbBjbTz0Y= -github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= -github.com/eapache/go-resiliency v1.2.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= -github.com/eapache/go-resiliency v1.6.0 h1:CqGDTLtpwuWKn6Nj3uNUdflaq+/kIPsg0gfNzHton30= -github.com/eapache/go-resiliency v1.6.0/go.mod h1:5yPzW0MIvSe0JDsv0v+DvcjEv2FyD6iZYSs1ZI+iQho= -github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= +github.com/eapache/go-resiliency v1.7.0 h1:n3NRTnBn5N0Cbi/IeOHuQn9s2UwVUH7Ga0ZWcP+9JTA= +github.com/eapache/go-resiliency v1.7.0/go.mod h1:5yPzW0MIvSe0JDsv0v+DvcjEv2FyD6iZYSs1ZI+iQho= github.com/eapache/go-xerial-snappy v0.0.0-20230731223053-c322873962e3 h1:Oy0F4ALJ04o5Qqpdz8XLIpNA3WM/iSIXqxtqo7UGVws= github.com/eapache/go-xerial-snappy v0.0.0-20230731223053-c322873962e3/go.mod h1:YvSRo5mw33fLEx1+DlK6L2VV43tJt5Eyel9n9XBcR+0= github.com/eapache/queue v1.1.0 h1:YOEu7KNc61ntiQlcEeUIoDTJ2o8mQznoNvUhiigpIqc= github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= -github.com/elastic/apm-aggregation v1.1.0 h1:eTHGd5w99JoRFJ763MJP6nUX4hkkeSil3KWiip7YtJY= -github.com/elastic/apm-aggregation v1.1.0/go.mod h1:YBQ77Jt7vOy2/7w4q5SsEifhc0V02dJxRcyyeC6HsvQ= -github.com/elastic/apm-data v1.13.1 h1:vQUWqi9H6QC4FCZ05kILkE+2BeKWw6iT+NXXyadWJm8= -github.com/elastic/apm-data v1.13.1/go.mod h1:m2FSH7alN07VmtmN10KmgxAa8tgXlJDe/rC0g4FnZUI= -github.com/elastic/beats/v7 v7.0.0-alpha2.0.20240823193033-af33fad4d50b h1:i3WdOw//Vg76Vseqxgn47GPTVqUSucAdE42jkih1ViM= -github.com/elastic/beats/v7 v7.0.0-alpha2.0.20240823193033-af33fad4d50b/go.mod h1:m8d3EBr2z7YvWfxRgoE7SsUNbMTpyWXi67fG7B7vn7w= -github.com/elastic/elastic-agent-autodiscover v0.8.1 h1:u6TWqh7wfevu6S4GUq4SIxYBRo4b/P5RZmx/rSvT10A= -github.com/elastic/elastic-agent-autodiscover v0.8.1/go.mod h1:0gzGsaDCAqBfUZjuCqqWsSI60eaZ778A5tQZV72rPV0= -github.com/elastic/elastic-agent-client/v7 v7.16.0 h1:yKGq2+CxAuW8Kh0EoNl202tqAyQKfBcPRawVKs2Jve0= -github.com/elastic/elastic-agent-client/v7 v7.16.0/go.mod h1:6h+f9QdIr3GO2ODC0Y8+aEXRwzbA5W4eV4dd/67z7nI= -github.com/elastic/elastic-agent-libs v0.12.1 h1:5jkxMx15Bna8cq7/Sz/XUIVUXfNWiJ80iSk4ICQ7KJ0= -github.com/elastic/elastic-agent-libs v0.12.1/go.mod h1:5CR02awPrBr+tfmjBBK+JI+dMmHNQjpVY24J0wjbC7M= -github.com/elastic/elastic-agent-system-metrics v0.11.3 h1:LDzRwP8kxvsYEtMDgMSKZs1TgPcSEukit+/EAP5Y28A= -github.com/elastic/elastic-agent-system-metrics v0.11.3/go.mod h1:saqLKe9fuyuAo6IADAnnuy1kaBI7VNlxfwMo8KzSRyQ= +github.com/ebitengine/purego v0.8.0 h1:JbqvnEzRvPpxhCJzJJ2y0RbiZ8nyjccVUrSM3q+GvvE= +github.com/ebitengine/purego v0.8.0/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ= +github.com/elastic/apm-aggregation v1.2.0 h1:UndqG3ccBTjyxTqHujBVjcbVLb9qG1clxRcrp9JRelI= +github.com/elastic/apm-aggregation v1.2.0/go.mod h1:YllYwPYVV27pbuPfjRtQAKo6eSSrh13PZr38RKYd810= +github.com/elastic/apm-data v1.16.0 h1:LkJFoNkadIyqXNo3EMm98J38j9HWDMWUe6F74GaXtJ4= +github.com/elastic/apm-data v1.16.0/go.mod h1:ST2P1yshhN2U3IbBYyn+Ni3VOFTifavNzMfh7E9zLHY= +github.com/elastic/beats/v7 v7.0.0-alpha2.0.20241231140711-7806f1a2cb26 h1:qyI4AIRfdnTwesqHN9KYdbGpcJ4m4lIKlR+f8zbKIO0= +github.com/elastic/beats/v7 v7.0.0-alpha2.0.20241231140711-7806f1a2cb26/go.mod h1:CgYrkUfXIWj/lcPc5ipnO0/2OEx4GmstkLzyUHilme8= +github.com/elastic/elastic-agent-autodiscover v0.9.0 h1:+iWIKh0u3e8I+CJa3FfWe9h0JojNasPgYIA47gpuuns= +github.com/elastic/elastic-agent-autodiscover v0.9.0/go.mod h1:5iUxLHhVdaGSWYTveSwfJEY4RqPXTG13LPiFoxcpFd4= +github.com/elastic/elastic-agent-client/v7 v7.17.0 h1:TPLrEHF4kJ3RkmQzZPffrniY4WeW4vriHZbOAzM1hFo= +github.com/elastic/elastic-agent-client/v7 v7.17.0/go.mod h1:6h+f9QdIr3GO2ODC0Y8+aEXRwzbA5W4eV4dd/67z7nI= +github.com/elastic/elastic-agent-libs v0.18.3 h1:bZ0e4Mrw7t6GnquTxzvZclGxZsUEIlsZNJPCPy2qO24= +github.com/elastic/elastic-agent-libs v0.18.3/go.mod h1:rWdyrrAFzZwgNNi41Tsqhlt2c2GdXWhCEwcsnqISJ2U= +github.com/elastic/elastic-agent-system-metrics v0.11.7 h1:1xm2okCM0eQZ4jivZgUFSlt6HAn/nPgKB/Fj8eLG6mY= +github.com/elastic/elastic-agent-system-metrics v0.11.7/go.mod h1:nzkrGajQA29YNcfP62gfzhxX9an3/xdQ3RmfQNw9YTI= github.com/elastic/elastic-transport-go/v8 v8.6.0 h1:Y2S/FBjx1LlCv5m6pWAF2kDJAHoSjSRSJCApolgfthA= github.com/elastic/elastic-transport-go/v8 v8.6.0/go.mod h1:YLHer5cj0csTzNFXoNQ8qhtGY1GTvSqPnKWKaqQE3Hk= github.com/elastic/gmux v0.3.2 h1:cb721R+fe/rt/jVNyBP5HDQsEwLD2wSKfPD2Sk6adDk= github.com/elastic/gmux v0.3.2/go.mod h1:OD6oYrno+SV3pyl1ArdWCjlExZ+FJOfoSaFqnFeldBQ= -github.com/elastic/go-docappender/v2 v2.3.0 h1:Vr+l36jM+sE/LHp0JFxSIbHlWTSk8CpBblYWZZ/I1KA= -github.com/elastic/go-docappender/v2 v2.3.0/go.mod h1:VNWgXUE9HX1G6W6ON8dOs/KdH8aCxXir/fxxcfrnov4= -github.com/elastic/go-elasticsearch/v8 v8.15.0 h1:IZyJhe7t7WI3NEFdcHnf6IJXqpRf+8S8QWLtZYYyBYk= -github.com/elastic/go-elasticsearch/v8 v8.15.0/go.mod h1:HCON3zj4btpqs2N1jjsAy4a/fiAul+YBP00mBH4xik8= +github.com/elastic/go-docappender/v2 v2.4.0 h1:3ouOEB7V4IDgjZ0YAggzDgMK63QFfQ9HcJWSyAZGRzY= +github.com/elastic/go-docappender/v2 v2.4.0/go.mod h1:Zm0mndWB4sS/9pgjMKdP0vOPJ1Cvkjy56B2D9DnGLgQ= +github.com/elastic/go-elasticsearch/v8 v8.17.0 h1:e9cWksE/Fr7urDRmGPGp47Nsp4/mvNOrU8As1l2HQQ0= +github.com/elastic/go-elasticsearch/v8 v8.17.0/go.mod h1:lGMlgKIbYoRvay3xWBeKahAiJOgmFDsjZC39nmO3H64= github.com/elastic/go-lumber v0.1.2-0.20220819171948-335fde24ea0f h1:TsPpU5EAwlt7YZoupKlxZ093qTZYdGou3EhfTF1U0B4= github.com/elastic/go-lumber v0.1.2-0.20220819171948-335fde24ea0f/go.mod h1:HHaWnZamYKWsR9/eZNHqRHob8iQDKnchHmmskT/SKko= github.com/elastic/go-structform v0.0.10 h1:oy08o/Ih2hHTkNcRY/1HhaYvIp5z6t8si8gnCJPDo1w= github.com/elastic/go-structform v0.0.10/go.mod h1:CZWf9aIRYY5SuKSmOhtXScE5uQiLZNqAFnwKR4OrIM4= -github.com/elastic/go-sysinfo v1.14.2 h1:DeIy+pVfdRsd08Nx2Xjh+dUS+jrEEI7LGc29U/BKVWo= -github.com/elastic/go-sysinfo v1.14.2/go.mod h1:jPSuTgXG+dhhh0GKIyI2Cso+w5lPJ5PvVqKlL8LV/Hk= +github.com/elastic/go-sysinfo v1.15.0 h1:54pRFlAYUlVNQ2HbXzLVZlV+fxS7Eax49stzg95M4Xw= +github.com/elastic/go-sysinfo v1.15.0/go.mod h1:jPSuTgXG+dhhh0GKIyI2Cso+w5lPJ5PvVqKlL8LV/Hk= github.com/elastic/go-ucfg v0.8.8 h1:54KIF/2zFKfl0MzsSOCGOsZ3O2bnjFQJ0nDJcLhviyk= github.com/elastic/go-ucfg v0.8.8/go.mod h1:4E8mPOLSUV9hQ7sgLEJ4bvt0KhMuDJa8joDT2QGAEKA= github.com/elastic/go-windows v1.0.2 h1:yoLLsAsV5cfg9FLhZ9EXZ2n2sQFKeDYrHenkcivY4vI= github.com/elastic/go-windows v1.0.2/go.mod h1:bGcDpBzXgYSqM0Gx3DM4+UxFj300SZLixie9u9ixLM8= +github.com/elastic/goja v0.0.0-20190128172624-dd2ac4456e20 h1:bVZ3kDKa8Tqw9qvNrD91MwJMW6alg4Wn31l1TQ6RlTY= +github.com/elastic/goja v0.0.0-20190128172624-dd2ac4456e20/go.mod h1:A1DWjF89MFVnxzmzTaMF7CwVy9PDem7DalMkm8RIMoY= github.com/elastic/gosigar v0.14.3 h1:xwkKwPia+hSfg9GqrCUKYdId102m9qTJIIr7egmK/uo= github.com/elastic/gosigar v0.14.3/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs= -github.com/elastic/opentelemetry-lib v0.9.0 h1:auMnq5zxqnB3eQNNdfz8+mtooy0D8+2ZEusU0sHeDj4= -github.com/elastic/opentelemetry-lib v0.9.0/go.mod h1:H4ECk7whGn41etgYL4zQWJ2BWN5xwP2A5HUIIwNrM9Y= +github.com/elastic/mock-es v0.0.0-20240712014503-e5b47ece0015 h1:z8cC8GASpPo8yKlbnXI36HQ/BM9wYjhBPNbDjAWm0VU= +github.com/elastic/mock-es v0.0.0-20240712014503-e5b47ece0015/go.mod h1:qH9DX/Dmflz6EAtaks/+2SsdQzecVAKE174Zl66hk7E= +github.com/elastic/opentelemetry-lib v0.14.0 h1:4P5q3RzwZTbAclHBmQp2dXxSsOMBQXZgkDStIR2iZnM= +github.com/elastic/opentelemetry-lib v0.14.0/go.mod h1:/FfOjBoi8gaKQrkhFxzxQzP5g7soH/tShRWDxfeIUq8= github.com/elastic/pkcs8 v1.0.0 h1:HhitlUKxhN288kcNcYkjW6/ouvuwJWd9ioxpjnD9jVA= github.com/elastic/pkcs8 v1.0.0/go.mod h1:ipsZToJfq1MxclVTwpG7U/bgeDtf+0HkUiOxebk95+0= -github.com/elastic/sarama v1.19.1-0.20210823122811-11c3ef800752 h1:5/RUNg7rkIvayjPhAIoI3v8p45NfWcfWs5DZSElycis= -github.com/elastic/sarama v1.19.1-0.20210823122811-11c3ef800752/go.mod h1:mdtqvCSg8JOxk8PmpTNGyo6wzd4BMm4QXSfDnTXmgkE= +github.com/elastic/sarama v1.19.1-0.20241120141909-c7eabfcee7e5 h1:U7rts7RrrzQSDKkMuECpw9QCafSn2nRp36eRnWyR14E= +github.com/elastic/sarama v1.19.1-0.20241120141909-c7eabfcee7e5/go.mod h1:EEdpKWvuZ46X7OEOENvSH5jEJXosi4fn7xjIeTajf+M= github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g= github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= +github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= +github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= -github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= -github.com/frankban/quicktest v1.14.0 h1:+cqqvzZV87b4adx/5ayVOaYZ2CrvM4ejQvUdBzPPUss= -github.com/frankban/quicktest v1.14.0/go.mod h1:NeW+ay9A/U67EYXNFA1nPE8e/tnQv/09mUdL/ijj8og= -github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/getsentry/sentry-go v0.27.0 h1:Pv98CIbtB3LkMWmXi4Joa5OOcwbmnX88sF5qbK3r3Ps= -github.com/getsentry/sentry-go v0.27.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY= +github.com/getsentry/sentry-go v0.29.1 h1:DyZuChN8Hz3ARxGVV8ePaNXh1dQ7d76AiB117xcREwA= +github.com/getsentry/sentry-go v0.29.1/go.mod h1:x3AtIzN01d6SiWkderzaH28Tm0lgkafpJ5Bm3li39O0= +github.com/ghemawat/stream v0.0.0-20171120220530-696b145b53b9 h1:r5GgOLGbza2wVHRzK7aAj6lWZjfbAwiu/RDCVOKjRyM= +github.com/ghemawat/stream v0.0.0-20171120220530-696b145b53b9/go.mod h1:106OIgooyS7OzLDOpUGgm9fA3bQENb/cFSyyBmMoJDs= github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA= github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= +github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= @@ -190,38 +186,37 @@ github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= -github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= -github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= -github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= -github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= -github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g= -github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= +github.com/go-openapi/jsonpointer v0.20.2 h1:mQc3nmndL8ZBzStEo3JYF8wzmeWffDH4VbXz58sAx6Q= +github.com/go-openapi/jsonpointer v0.20.2/go.mod h1:bHen+N0u1KEO3YlmqOjTT9Adn1RfD91Ar825/PuiRVs= +github.com/go-openapi/jsonreference v0.20.4 h1:bKlDxQxQJgwpUSgOENiMPzCTBVuc7vTdXSSgNeAhojU= +github.com/go-openapi/jsonreference v0.20.4/go.mod h1:5pZJyJP2MnYCpoeoMAql78cCHauHj0V9Lhc506VOpw4= +github.com/go-openapi/swag v0.22.9 h1:XX2DssF+mQKM2DHsbgZK74y/zj4mo9I99+89xUmuZCE= +github.com/go-openapi/swag v0.22.9/go.mod h1:3/OXnFfnMAwBD099SwYRk7GD3xOrr1iL7d/XNLXVVwE= github.com/go-sourcemap/sourcemap v2.1.4+incompatible h1:a+iTbH5auLKxaNwQFg0B+TCYl6lbukKPc7b5x0n1s6Q= github.com/go-sourcemap/sourcemap v2.1.4+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/gofrs/flock v0.12.1 h1:MTLVXXHf8ekldpJk3AKicLij9MdwOWkZ+a/jHHZby9E= github.com/gofrs/flock v0.12.1/go.mod h1:9zxTsyu5xtJ9DK+1tFZyibEV7y3uwDxPPfbxeeHCoD0= -github.com/gofrs/uuid v4.4.0+incompatible h1:3qXRTX8/NbyulANqlc0lchS1gqAVxRgsuW1YrTJupqA= -github.com/gofrs/uuid v4.4.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= -github.com/gofrs/uuid/v5 v5.2.0 h1:qw1GMx6/y8vhVsx626ImfKMuS5CvJmhIKKtuyvfajMM= -github.com/gofrs/uuid/v5 v5.2.0/go.mod h1:CDOjlDMVAtN56jqyRUZh58JT31Tiw7/oQyEXZV+9bD8= -github.com/gogo/googleapis v1.4.1 h1:1Yx4Myt7BxzvUr5ldGSbwYiZG6t9wGBZ+8/fX3Wvtq0= -github.com/gogo/googleapis v1.4.1/go.mod h1:2lpHqI5OcWCtVElxXnPt+s8oJvMpySlOyM6xDCrzib4= +github.com/gofrs/uuid/v5 v5.3.0 h1:m0mUMr+oVYUdxpMLgSYCZiXe7PuVPnI94+OMeVBNedk= +github.com/gofrs/uuid/v5 v5.3.0/go.mod h1:CDOjlDMVAtN56jqyRUZh58JT31Tiw7/oQyEXZV+9bD8= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk= github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= -github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= -github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= -github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.5-0.20231225225746-43d5d4cd4e0e h1:4bw4WeyTYPp0smaXiJZCNnLrvVBqirQVreixayXezGc= +github.com/golang/snappy v0.0.5-0.20231225225746-43d5d4cd4e0e/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/gomodule/redigo v1.8.9 h1:Sl3u+2BI/kk+VEatbj0scLdrFhjPmbxOc1myhDP41ws= github.com/gomodule/redigo v1.8.9/go.mod h1:7ArFNvsTjH8GMMzB4uy1snslv2BwmginuMs06a1uzZE= github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= -github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= @@ -234,35 +229,36 @@ github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= +github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyCS8BvQ= github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4= +github.com/gorilla/sessions v1.2.1 h1:DHd3rPN5lE3Ts3D8rKkQ8x/0kqfeNmBAaiSi+o7FsgI= github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM= -github.com/grpc-ecosystem/go-grpc-middleware v1.0.0 h1:Iju5GlWwrvL6UBg4zJJt3btmonfrMlCDdsejg4CZE7c= -github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 h1:+9834+KizmvFV7pXQGSXQTsaWhq2GjuNUt0aUU0YBYw= +github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y= github.com/h2non/filetype v1.1.3 h1:FKkx9QbD7HR/zjK1Ia5XiBsq9zdLi5Kf3zGyFTAFkGg= github.com/h2non/filetype v1.1.3/go.mod h1:319b3zT68BvV+WRj7cwy856M2ehB3HqNOt6sy1HndBY= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= +github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= +github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/golang-lru v1.0.2 h1:dV3g9Z/unq5DpblPpw+Oqcv4dU/1omnb4Ok8iPY6p1c= github.com/hashicorp/golang-lru v1.0.2/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= -github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/imdario/mergo v0.3.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk= -github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg= -github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= +github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -github.com/jaegertracing/jaeger v1.60.0 h1:6fswbNydmXJNH7uz2smy2fFs9KKRpLrFXdW0u/hud4o= -github.com/jaegertracing/jaeger v1.60.0/go.mod h1:CMrmMLIWn7xLP0IwBgpbxtgIuOT6TF/7bpTUBaOUaXo= github.com/jcmturner/aescts/v2 v2.0.0 h1:9YKLH6ey7H4eDBXW8khjYslgyqG2xZikXP0EQFKrle8= github.com/jcmturner/aescts/v2 v2.0.0/go.mod h1:AiaICIRyfYg35RUkr8yESTqvSy7csK90qZ5xfvvsoNs= github.com/jcmturner/dnsutils/v2 v2.0.0 h1:lltnkeZGL0wILNvrNiVCR6Ro5PGU/SeBvVO/8c/iPbo= github.com/jcmturner/dnsutils/v2 v2.0.0/go.mod h1:b0TnjGOvI/n42bZa+hmXL+kFJZsFT7G4t3HTlQ184QM= -github.com/jcmturner/gofork v1.0.0/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o= github.com/jcmturner/gofork v1.7.6 h1:QH0l3hzAU1tfT3rZCnW5zXl+orbkNMMRGJfdJjHVETg= github.com/jcmturner/gofork v1.7.6/go.mod h1:1622LH6i/EZqLloHfE7IeZ0uEJwMSUyQ/nDd82IeqRo= github.com/jcmturner/goidentity/v6 v6.0.1 h1:VKnZd2oEIMorCTsFBnJWbExfNN7yZr3EhJAxwOkZg6o= github.com/jcmturner/goidentity/v6 v6.0.1/go.mod h1:X1YW3bgtvwAXju7V3LCIMpY0Gbxyjn/mY9zx4tFonSg= -github.com/jcmturner/gokrb5/v8 v8.4.2/go.mod h1:sb+Xq/fTY5yktf/VxLsE3wlfPqQjp0aWNYyvBVK62bc= github.com/jcmturner/gokrb5/v8 v8.4.4 h1:x1Sv4HaTpepFkXbt2IkL29DXRf8sOfZXo8eRKh687T8= github.com/jcmturner/gokrb5/v8 v8.4.4/go.mod h1:1btQEpgT6k+unzCwX1KdWMEwPPkkgBtP+F6aCACiMrs= github.com/jcmturner/rpc/v2 v2.0.3 h1:7FXXj8Ti1IaVFpSAziCZWNzbNuZmnvw/i6CqLNdWfZY= @@ -276,13 +272,11 @@ github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnr github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/klauspost/compress v1.12.2/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= -github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= -github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= -github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= +github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc= +github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= @@ -295,7 +289,6 @@ github.com/libp2p/go-reuseport v0.4.0 h1:nR5KU7hD0WxXCJbmw7r2rhRYruNRl2koHw8fQsc github.com/libp2p/go-reuseport v0.4.0/go.mod h1:ZtI03j/wO5hZVDFo2jKywN6bYKWLOy8Se6DrI2E1cLU= github.com/lufia/plan9stats v0.0.0-20220913051719-115f729f3c8c h1:VtwQ41oftZwlMnOEbMWQtSEUgU64U4s+GHk7hZK+jtY= github.com/lufia/plan9stats v0.0.0-20220913051719-115f729f3c8c/go.mod h1:JKx41uQRwqlTZabZc+kILPrO/3jlKnQ2Z8b7YiVw5cE= -github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= @@ -303,10 +296,12 @@ github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovk github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mileusna/useragent v1.3.4 h1:MiuRRuvGjEie1+yZHO88UBYg8YBC/ddF6T7F56i3PCk= +github.com/mileusna/useragent v1.3.4/go.mod h1:3d8TOmwL/5I8pJjyVDteHtgDGcefrFUX4ccGOMKNYYc= github.com/mitchellh/hashstructure v1.1.0 h1:P6P1hdjqAAknpY/M1CGipelZgp+4y9ja9kmUZPXP+H0= github.com/mitchellh/hashstructure v1.1.0/go.mod h1:xUDAozZz0Wmdiufv0uyhnHkUTN6/6d8ulp4AwfLKrmA= -github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0= +github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -315,20 +310,15 @@ github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjY github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= -github.com/open-telemetry/opentelemetry-collector-contrib/internal/coreinternal v0.109.0 h1:4VBRgtyh3hHSgAVGgs4bvNwJd0oUGyxVA3eQO2ujNsA= -github.com/open-telemetry/opentelemetry-collector-contrib/internal/coreinternal v0.109.0/go.mod h1:9MGQCqxdCNBhdD+7QBZ6hH9HipXe5CajMafVKglD5f0= -github.com/open-telemetry/opentelemetry-collector-contrib/pkg/translator/jaeger v0.109.0 h1:CSYFxtxCBTF7BHbITx3g5ilxsjAI2Mn5nDHotnU4KXg= -github.com/open-telemetry/opentelemetry-collector-contrib/pkg/translator/jaeger v0.109.0/go.mod h1:D0jbiFn1iOXtc/lfotbBKayP3KWUIYdc00GmTFcsWds= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug= github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM= +github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc= github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= -github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= -github.com/pierrec/lz4 v2.6.0+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= -github.com/pierrec/lz4 v2.6.1+incompatible h1:9UY3+iC23yxF0UfGaYrGplQ+79Rg+h/q9FV9ix19jjM= -github.com/pierrec/lz4 v2.6.1+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= +github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 h1:onHthvaw9LFnH4t2DcNVpwGmV9E1BkGknEliJkfwQj0= +github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58/go.mod h1:DXv8WO4yhMYhSNPKjeNKa5WY9YCIEBRbNzFFPJbWO6Y= github.com/pierrec/lz4/v4 v4.1.21 h1:yOVMLb6qSIDP67pl/5F7RepeKYu/VmTyEXvuMI5d9mQ= github.com/pierrec/lz4/v4 v4.1.21/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4= @@ -348,48 +338,32 @@ github.com/power-devops/perfstat v0.0.0-20220216144756-c35f1ee13d7c h1:NRoLoZvkB github.com/power-devops/perfstat v0.0.0-20220216144756-c35f1ee13d7c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g= github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U= -github.com/prometheus/client_golang v1.20.2 h1:5ctymQzZlyOON1666svgwn3s6IKWgfbjsejTMiXIyjg= -github.com/prometheus/client_golang v1.20.2/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= +github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y= +github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= -github.com/prometheus/common v0.57.0 h1:Ro/rKjwdq9mZn1K5QPctzh+MA4Lp0BuYk5ZZEVhoNcY= -github.com/prometheus/common v0.57.0/go.mod h1:7uRPFSUTbfZWsJ7MHY56sqt7hLQu3bxXHDnNhl8E9qI= +github.com/prometheus/common v0.60.1 h1:FUas6GcOw66yB/73KC+BOZoFJmbo/1pojoILArPAaSc= +github.com/prometheus/common v0.60.1/go.mod h1:h0LYf1R1deLSKtD4Vdg8gy4RuOvENW2J/h19V5NADQw= github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= -github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= -github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= -github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= -github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= +github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= +github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkBk= github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc= -github.com/shirou/gopsutil/v3 v3.24.5 h1:i0t8kL+kQTvpAYToeuiVk3TgDeKOFioZO3Ztz/iZ9pI= -github.com/shirou/gopsutil/v3 v3.24.5/go.mod h1:bsoOS1aStSs9ErQ1WWfxllSeS1K5D+U30r2NfcubMVk= -github.com/shirou/gopsutil/v4 v4.24.7 h1:V9UGTK4gQ8HvcnPKf6Zt3XHyQq/peaekfxpJ2HSocJk= -github.com/shirou/gopsutil/v4 v4.24.7/go.mod h1:0uW/073rP7FYLOkvxolUQM5rMOLTNmRXnFKafpb71rw= -github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM= -github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ= -github.com/shoenig/test v0.6.4 h1:kVTaSd7WLz5WZ2IaoM0RSzRsUD+m8wRR+5qvntpn4LU= -github.com/shoenig/test v0.6.4/go.mod h1:byHiCGXqrVaflBLAMq/srcZIHynQPQgeyvkvXnjqq0k= -github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= -github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= -github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= -github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= -github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= -github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= +github.com/shirou/gopsutil/v4 v4.24.9 h1:KIV+/HaHD5ka5f570RZq+2SaeFsb/pq+fp2DGNWYoOI= +github.com/shirou/gopsutil/v4 v4.24.9/go.mod h1:3fkaHNeYsUFCGZ8+9vZVWtbyM1k2eRnlL+bWO8Bxa/Q= +github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= -github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= -github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= @@ -397,105 +371,113 @@ github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU= github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI= github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk= github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY= -github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c= github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= github.com/xdg-go/scram v1.1.2 h1:FHX5I5B4i4hKRVRBCFRxq1iQRej7WO3hhBuJf+UUySY= github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3kKLN4= github.com/xdg-go/stringprep v1.0.4 h1:XLI/Ng3O1Atzq0oBs3TWm+5ZVgkq2aqdlvP9JtoZ6c8= github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM= -github.com/xdg/scram v1.0.3/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I= -github.com/xdg/stringprep v1.0.3/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y= github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo= github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= -github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0= github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= -go.elastic.co/apm/module/apmelasticsearch/v2 v2.6.2 h1:x5LIkBAIo2XT8nBqoAjPeJKUJC94le7D9aclBYP9uCw= -go.elastic.co/apm/module/apmelasticsearch/v2 v2.6.2/go.mod h1:LkYiSaKsGns6yRqXKAMbFyz7Nk8ikPCD/5CGkgQOY/A= -go.elastic.co/apm/module/apmgorilla/v2 v2.6.2 h1:/myBx0D/JiwTUjFkVFG3zXmDfGPfQjP/cg27qcBbdfU= -go.elastic.co/apm/module/apmgorilla/v2 v2.6.2/go.mod h1:uONZzSIh/cKjQ2rZmINR1VXVOJDq5eWOzKrCY+bu00w= -go.elastic.co/apm/module/apmgrpc/v2 v2.6.2 h1:jaQeR7uZx9kF4JpMMwAxxyMu6xqWErt4poyqUq8TUrg= -go.elastic.co/apm/module/apmgrpc/v2 v2.6.2/go.mod h1:AXDoIt5+0FWl8w2ev/M+dSU4J//SMS6V20wdiiUWPLE= -go.elastic.co/apm/module/apmhttp/v2 v2.6.2 h1:+aYtP1Lnrsm+XtEs87RWG2PAyU6LHDDnYnJl3Lth0Qk= -go.elastic.co/apm/module/apmhttp/v2 v2.6.2/go.mod h1:vlH+vXHaEijKK4pk605LOK+lbLDKwcByhlq4J24PeXw= -go.elastic.co/apm/module/apmotel/v2 v2.6.2 h1:48hxUEPRwwcHpsDSde5P5a05ut6gTkq3oO1c6HrTjMI= -go.elastic.co/apm/module/apmotel/v2 v2.6.2/go.mod h1:ZvyYDHJi49W42XhxmAYyDVtJhiEIaeB+RBgoHgzigM4= -go.elastic.co/apm/module/apmzap/v2 v2.6.0 h1:R/iVORzGu3F9uM43iEVHD0nwiRo59O0bIXdayKsgayQ= -go.elastic.co/apm/module/apmzap/v2 v2.6.0/go.mod h1:B3i/8xRkqLgi6zNuV+Bp7Pt4cutaOObvrVSa7wUTAPw= -go.elastic.co/apm/v2 v2.6.2 h1:VBplAxgbOgTv+Giw/FS91xJpHYw/q8fz/XKPvqC+7/o= -go.elastic.co/apm/v2 v2.6.2/go.mod h1:33rOXgtHwbgZcDgi6I/GtCSMZQqgxkHC0IQT3gudKvo= +go.elastic.co/apm/module/apmelasticsearch/v2 v2.6.3 h1:5CuemBg1oZnXI6jz+jkLqM95Np1XHasdy0CCelX62Ec= +go.elastic.co/apm/module/apmelasticsearch/v2 v2.6.3/go.mod h1:MVK2TIrvMGQaL7bnO4dbnJ+jpDNqmkj+BukDRBYTI60= +go.elastic.co/apm/module/apmgorilla/v2 v2.6.3 h1:7PYs7pOL7MLNV1m+SSjeUacBTdxozRxOv0l81U0UP0g= +go.elastic.co/apm/module/apmgorilla/v2 v2.6.3/go.mod h1:TbZz10D10TVn/WjxnGU9A6Y/nuZv82ECkOdG1tlhx1U= +go.elastic.co/apm/module/apmgrpc/v2 v2.6.3 h1:HBj41BO8rsV0gbSeBRDBSbi4SMLr+EnWsn2l7gJ8qM4= +go.elastic.co/apm/module/apmgrpc/v2 v2.6.3/go.mod h1:RWmwuJXPuIFl7AqRKD/KMQwM1EKqRJ3JUecyQiDjiHY= +go.elastic.co/apm/module/apmhttp/v2 v2.6.3 h1:jwFovJZkccySKCyy2oE9ZKvUry/a4gdQHF/MtZUQVtE= +go.elastic.co/apm/module/apmhttp/v2 v2.6.3/go.mod h1:w94Gkk6uzI/K+eJYKDLB66tvWC5uK0fSHyWcyX2jPlQ= +go.elastic.co/apm/module/apmotel/v2 v2.6.3 h1:E0LybEjMe0ikj9Q/Z5Ag4qzMXKwvsoWwEQRjf7CCUes= +go.elastic.co/apm/module/apmotel/v2 v2.6.3/go.mod h1:8Kk5SLyr6mHZRxmM02FqS/9SYu2w6EnKImYx8KW6L+Q= +go.elastic.co/apm/module/apmzap/v2 v2.6.3 h1:QxszhmFs2qD42sHSd6qnZUv5xMPV7cVSIt1qU/o4nwA= +go.elastic.co/apm/module/apmzap/v2 v2.6.3/go.mod h1:gOs+EJgXDCyg1pK4pcxN6fL9hKNC+s/Hj20e9RvGeJg= +go.elastic.co/apm/v2 v2.6.3 h1:yVKFPLnmHOxpzLMGd3aexcik20ziXmRHqgcn9NZn/VU= +go.elastic.co/apm/v2 v2.6.3/go.mod h1:33rOXgtHwbgZcDgi6I/GtCSMZQqgxkHC0IQT3gudKvo= go.elastic.co/ecszap v1.0.2 h1:iW5OGx8IiokiUzx/shD4AJCPFMC9uUtr7ycaiEIU++I= go.elastic.co/ecszap v1.0.2/go.mod h1:dJkSlK3BTiwG/qXhCwe50Mz/jwu854vSip8sIeQhNZg= go.elastic.co/fastjson v1.4.0 h1:a4BXUKXZHAzjVOPrqtEx2FDsIRBCMek01vCnrtyutWs= go.elastic.co/fastjson v1.4.0/go.mod h1:ZD5um63l0/8TIdddZbL2znD83FAr2IckYa3KR7VcdNA= -go.opentelemetry.io/collector/consumer v0.109.0 h1:fdXlJi5Rat/poHPiznM2mLiXjcv1gPy3fyqqeirri58= -go.opentelemetry.io/collector/consumer v0.109.0/go.mod h1:E7PZHnVe1DY9hYy37toNxr9/hnsO7+LmnsixW8akLQI= -go.opentelemetry.io/collector/pdata v1.15.0 h1:q/T1sFpRKJnjDrUsHdJ6mq4uSqViR/f92yvGwDby/gY= -go.opentelemetry.io/collector/pdata v1.15.0/go.mod h1:2wcsTIiLAJSbqBq/XUUYbi+cP+N87d0jEJzmb9nT19U= -go.opentelemetry.io/collector/semconv v0.109.0 h1:6CStOFOVhdrzlHg51kXpcPHRKPh5RtV7z/wz+c1TG1g= -go.opentelemetry.io/collector/semconv v0.109.0/go.mod h1:zCJ5njhWpejR+A40kiEoeFm1xq1uzyZwMnRNX6/D82A= -go.opentelemetry.io/otel v1.30.0 h1:F2t8sK4qf1fAmY9ua4ohFS/K+FUuOPemHUIXHtktrts= -go.opentelemetry.io/otel v1.30.0/go.mod h1:tFw4Br9b7fOS+uEao81PJjVMjW/5fvNCbpsDIXqP0pc= -go.opentelemetry.io/otel/metric v1.30.0 h1:4xNulvn9gjzo4hjg+wzIKG7iNFEaBMX00Qd4QIZs7+w= -go.opentelemetry.io/otel/metric v1.30.0/go.mod h1:aXTfST94tswhWEb+5QjlSqG+cZlmyXy/u8jFpor3WqQ= -go.opentelemetry.io/otel/sdk v1.30.0 h1:cHdik6irO49R5IysVhdn8oaiR9m8XluDaJAs4DfOrYE= -go.opentelemetry.io/otel/sdk v1.30.0/go.mod h1:p14X4Ok8S+sygzblytT1nqG98QG2KYKv++HE0LY/mhg= -go.opentelemetry.io/otel/sdk/metric v1.30.0 h1:QJLT8Pe11jyHBHfSAgYH7kEmT24eX792jZO1bo4BXkM= -go.opentelemetry.io/otel/sdk/metric v1.30.0/go.mod h1:waS6P3YqFNzeP01kuo/MBBYqaoBJl7efRQHOaydhy1Y= -go.opentelemetry.io/otel/trace v1.30.0 h1:7UBkkYzeg3C7kQX8VAidWh2biiQbtAKjyIML8dQ9wmc= -go.opentelemetry.io/otel/trace v1.30.0/go.mod h1:5EyKqTzzmyqB9bwtCCq6pDLktPK6fmGf/Dph+8VI02o= +go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= +go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= +go.opentelemetry.io/collector/consumer v1.22.0 h1:QmfnNizyNZFt0uK3GG/EoT5h6PvZJ0dgVTc5hFEc1l0= +go.opentelemetry.io/collector/consumer v1.22.0/go.mod h1:tiz2khNceFAPokxxfzAuFfIpShBasMT2AL2Sbc7+m0I= +go.opentelemetry.io/collector/pdata v1.24.0 h1:D6j92eAzmAbQgivNBUnt8r9juOl8ugb+ihYynoFZIEg= +go.opentelemetry.io/collector/pdata v1.24.0/go.mod h1:cf3/W9E/uIvPS4MR26SnMFJhraUCattzzM6qusuONuc= +go.opentelemetry.io/collector/semconv v0.116.0 h1:63xCZomsKJAWmKGWD3lnORiE3WKW6AO4LjnzcHzGx3Y= +go.opentelemetry.io/collector/semconv v0.116.0/go.mod h1:N6XE8Q0JKgBN2fAhkUQtqK9LT7rEGR6+Wu/Rtbal1iI= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0 h1:TT4fX+nBOA/+LUkobKGW1ydGcn+G3vRw9+g5HwCphpk= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0/go.mod h1:L7UH0GbB0p47T4Rri3uHjbpCFYrVrwc1I25QhNPiGK8= +go.opentelemetry.io/otel v1.34.0 h1:zRLXxLCgL1WyKsPVrgbSdMN4c0FMkDAskSTQP+0hdUY= +go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI= +go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ= +go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE= +go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A= +go.opentelemetry.io/otel/sdk v1.34.0/go.mod h1:0e/pNiaMAqaykJGKbi+tSjWfNNHMTxoC9qANsCzbyxU= +go.opentelemetry.io/otel/sdk/metric v1.34.0 h1:5CeK9ujjbFVL5c1PhLuStg1wxA7vQv7ce1EK0Gyvahk= +go.opentelemetry.io/otel/sdk/metric v1.34.0/go.mod h1:jQ/r8Ze28zRKoNRdkjCZxfs6YvBTG1+YIqyFVFYec5w= +go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k= +go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE= +go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs= go.uber.org/automaxprocs v1.6.0/go.mod h1:ifeIMSnPZuznNm6jmdzmU3/bfk01Fe2fotchwEFJ8r8= go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= +go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= -golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +go.uber.org/zap/exp v0.3.0 h1:6JYzdifzYkGmTdRR59oYH+Ng7k49H9qVpWwNSsGJj3U= +go.uber.org/zap/exp v0.3.0/go.mod h1:5I384qq7XGxYyByIhHm6jg5CHkGY0nsTfbDLgDDlgJQ= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20201112155050-0c6587e931a9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= -golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw= -golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U= -golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 h1:vr/HnozRka3pE4EsMEg1lgkXJkTFJCVUX+S/ZT6wYzM= -golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc= +golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc= +golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c h1:7dEasQXItcW1xKJ2+gg5VOiBnqWrJc+rq0DPKyvvdbY= +golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c/go.mod h1:NQtJDoLvd6faHhE7m4T/1IY708gDefGGjR/iUW8yQQ8= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -504,71 +486,73 @@ golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= -golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4= -golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU= -golang.org/x/oauth2 v0.22.0 h1:BzDx2FehcG7jJwgWLELCdmLuxk2i+x9UDpSiss2u0ZA= -golang.org/x/oauth2 v0.22.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0= +golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.24.0 h1:KTBBxWqUa0ykRPLtV69rRto9TLXcqYkeswu48x/gvNE= +golang.org/x/oauth2 v0.24.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= -golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= +golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180810173357-98c5dad5d1a0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= -golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= +golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk= -golang.org/x/term v0.25.0 h1:WtHI/ltw4NvSUig5KARz9h521QvRC8RmF/cuYqifU24= -golang.org/x/term v0.25.0/go.mod h1:RPyXicDX+6vLxogjjRxjgD2TKtmAO6NZBsBRfrOLu7M= +golang.org/x/term v0.28.0 h1:/Ts8HFuMR2E6IP/jlo7QVLZHggjKQbhu/7H0LJFr3Gg= +golang.org/x/term v0.28.0/go.mod h1:Sw/lC2IAUZ92udQNf3WodGtn4k/XoLyZoh8v/8uiwek= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= -golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= -golang.org/x/time v0.7.0 h1:ntUhktv3OPE6TgYxXWv9vKvUSJyIFJlyohwbkEwPrKQ= -golang.org/x/time v0.7.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= +golang.org/x/time v0.9.0 h1:EsRrnYcQiGH+5FfbgvV4AP7qEZstoyrHB0DzarOQ4ZY= +golang.org/x/time v0.9.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= @@ -579,34 +563,32 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240822170219-fc7c04adadcd h1:6TEm2ZxXoQmFWFlt1vNxvVOa1Q0dXFQD1m/rYjXmS0E= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240822170219-fc7c04adadcd/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= -google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= -google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto/googleapis/rpc v0.0.0-20241209162323-e6fa225c2576 h1:8ZmaLZE4XWrtU3MyClkYqqtl6Oegr3235h7jxsDyqCY= +google.golang.org/genproto/googleapis/rpc v0.0.0-20241209162323-e6fa225c2576/go.mod h1:5uTbfoYQed2U9p3KIj2/Zzm02PYhndfdmML0qC3q3FU= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= +google.golang.org/grpc v1.70.0 h1:pWFv03aZoHzlRKHWicjsZytKAiYCtNS0dHbXnIdq7jQ= +google.golang.org/grpc v1.70.0/go.mod h1:ofIJqVKDXx/JiXrwr2IG4/zwdH9txy3IlF40RmcJSQw= google.golang.org/grpc/examples v0.0.0-20231016154744-cb430bed4d27 h1:EB/3dtnYKOItaNPpOI/HmOCGbVZUiXcstRfiuxN+cFg= google.golang.org/grpc/examples v0.0.0-20231016154744-cb430bed4d27/go.mod h1:Crtq1t+mykyL5d6PR3z8zCxKx/Qjq/mlPWDPoWJANYA= -google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA= -google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +google.golang.org/protobuf v1.36.4 h1:6A3ZDJHn/eNqc1i+IdefRzy/9PokBTPvcqMySR7NNIM= +google.golang.org/protobuf v1.36.4/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/hjson/hjson-go.v3 v3.0.1/go.mod h1:X6zrTSVeImfwfZLfgQdInl9mWjqPqgH90jom9nym/lw= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= -gopkg.in/jcmturner/aescts.v1 v1.0.1 h1:cVVZBK2b1zY26haWB4vbBiZrfFQnfbTVrE3xZq6hrEw= -gopkg.in/jcmturner/aescts.v1 v1.0.1/go.mod h1:nsR8qBOg+OucoIW+WMhB3GspUQXq9XorLnQb9XtvcOo= -gopkg.in/jcmturner/dnsutils.v1 v1.0.1 h1:cIuC1OLRGZrld+16ZJvvZxVJeKPsvd5eUIvxfoN5hSM= -gopkg.in/jcmturner/dnsutils.v1 v1.0.1/go.mod h1:m3v+5svpVOhtFAP/wSz+yzh4Mc0Fg7eRhxkJMWSIz9Q= -gopkg.in/jcmturner/goidentity.v3 v3.0.0 h1:1duIyWiTaYvVx3YX2CYtpJbUFd7/UuPYCfgXtQ3VTbI= -gopkg.in/jcmturner/goidentity.v3 v3.0.0/go.mod h1:oG2kH0IvSYNIu80dVAyu/yoefjq1mNfM5bm88whjWx4= -gopkg.in/jcmturner/gokrb5.v7 v7.5.0 h1:a9tsXlIDD9SKxotJMK3niV7rPZAJeX2aD/0yg3qlIrg= -gopkg.in/jcmturner/gokrb5.v7 v7.5.0/go.mod h1:l8VISx+WGYp+Fp7KRbsiUuXTTOnxIc3Tuvyavf11/WM= -gopkg.in/jcmturner/rpc.v1 v1.1.0 h1:QHIUxTX1ISuAv9dD2wJ9HWQVuWDX/Zc0PfeC2tjc4rU= -gopkg.in/jcmturner/rpc.v1 v1.1.0/go.mod h1:YIdkC4XfD6GXbzje11McwsDuOlZQSb9W4vfLvuNnlv8= gopkg.in/mcuadros/go-syslog.v2 v2.3.0 h1:kcsiS+WsTKyIEPABJBJtoG0KkOS6yzvJ+/eZlhD79kk= gopkg.in/mcuadros/go-syslog.v2 v2.3.0/go.mod h1:l5LPIyOOyIdQquNg+oU6Z3524YwrcqEm0aKH+5zpt2U= gopkg.in/yaml.v1 v1.0.0-20140924161607-9f9df34309c0/go.mod h1:WDnlLJ4WF5VGsH/HVa3CI79GS0ol3YnhVnKP89i0kNg= @@ -615,10 +597,10 @@ gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= howett.net/plist v1.0.1 h1:37GdZ8tP09Q35o9ych3ehygcsL+HqKSwzctveSlarvM= howett.net/plist v1.0.1/go.mod h1:lqaXoTrLY4hg8tnEzNru53gicrbv7rrk+2xJA/7hw9g= k8s.io/api v0.29.5 h1:levS+umUigHCfI3riD36pMY1vQEbrzh4r1ivVWAhHaI= @@ -627,10 +609,10 @@ k8s.io/apimachinery v0.29.5 h1:Hofa2BmPfpoT+IyDTlcPdCHSnHtEQMoJYGVoQpRTfv4= k8s.io/apimachinery v0.29.5/go.mod h1:i3FJVwhvSp/6n8Fl4K97PJEP8C+MM+aoDq4+ZJBf70Y= k8s.io/client-go v0.29.5 h1:nlASXmPQy190qTteaVP31g3c/wi2kycznkTP7Sv1zPc= k8s.io/client-go v0.29.5/go.mod h1:aY5CnqUUvXYccJhm47XHoPcRyX6vouHdIBHaKZGTbK4= -k8s.io/klog/v2 v2.110.1 h1:U/Af64HJf7FcwMcXyKm2RPM22WZzyR7OSpYj5tg3cL0= -k8s.io/klog/v2 v2.110.1/go.mod h1:YGtd1984u+GgbuZ7e08/yBuAfKLSO0+uR1Fhi6ExXjo= -k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 h1:aVUu9fTY98ivBPKR9Y5w/AuzbMm96cd3YHRTU83I780= -k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00/go.mod h1:AsvuZPBlUDVuCdzJ87iajxtXuR9oktsTctW/R9wwouA= +k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= +k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= +k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 h1:BZqlfIlq5YbRMFko6/PM7FjZpUb45WallggurYhKGag= +k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340/go.mod h1:yD4MZYeKMBwQKVht279WycxKyM84kkAx2DPrTXaeb98= k8s.io/utils v0.0.0-20230726121419-3b25d923346b h1:sgn3ZU783SCgtaSJjpcVVlRqd6GSnlTLKgpAAttJvpI= k8s.io/utils v0.0.0-20230726121419-3b25d923346b/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= kernel.org/pub/linux/libs/security/libcap/cap v1.2.57 h1:2nmqI+aw7EQZuelYktkQHBE4jESD2tOR+lOJEnv/Apo= diff --git a/internal/agentcfg/elasticsearch.go b/internal/agentcfg/elasticsearch.go index 066b9374817..bf01ddf7114 100644 --- a/internal/agentcfg/elasticsearch.go +++ b/internal/agentcfg/elasticsearch.go @@ -29,11 +29,11 @@ import ( "github.com/pkg/errors" "go.elastic.co/apm/v2" + "go.opentelemetry.io/otel/metric" "github.com/elastic/apm-server/internal/elasticsearch" "github.com/elastic/apm-server/internal/logs" "github.com/elastic/elastic-agent-libs/logp" - "github.com/elastic/elastic-agent-libs/monitoring" "github.com/elastic/go-elasticsearch/v8/esapi" ) @@ -71,14 +71,15 @@ type ElasticsearchFetcher struct { logger, rateLimitedLogger *logp.Logger - tracer *apm.Tracer - metrics fetcherMetrics -} + tracer *apm.Tracer -type fetcherMetrics struct { - fetchES, fetchFallback, fetchFallbackUnavailable, fetchInvalid, - cacheRefreshSuccesses, cacheRefreshFailures, - cacheEntriesCount atomic.Int64 + esCacheEntriesCount metric.Int64Gauge + esFetchCount metric.Int64Counter + esFetchFallbackCount metric.Int64Counter + esFetchUnavailableCount metric.Int64Counter + esFetchInvalidCount metric.Int64Counter + esCacheRefreshSuccesses metric.Int64Counter + esCacheRefreshFailures metric.Int64Counter } func NewElasticsearchFetcher( @@ -86,7 +87,18 @@ func NewElasticsearchFetcher( cacheDuration time.Duration, fetcher Fetcher, tracer *apm.Tracer, + mp metric.MeterProvider, ) *ElasticsearchFetcher { + meter := mp.Meter("github.com/elastic/apm-server/internal/agentcfg") + + esCacheEntriesCount, _ := meter.Int64Gauge("apm-server.agentcfg.elasticsearch.cache.entries.count") + esFetchCount, _ := meter.Int64Counter("apm-server.agentcfg.elasticsearch.fetch.es") + esFetchFallbackCount, _ := meter.Int64Counter("apm-server.agentcfg.elasticsearch.fetch.fallback") + esFetchUnavailableCount, _ := meter.Int64Counter("apm-server.agentcfg.elasticsearch.fetch.unavailable") + esFetchInvalidCount, _ := meter.Int64Counter("apm-server.agentcfg.elasticsearch.fetch.invalid") + esCacheRefreshSuccesses, _ := meter.Int64Counter("apm-server.agentcfg.elasticsearch.cache.refresh.successes") + esCacheRefreshFailures, _ := meter.Int64Counter("apm-server.agentcfg.elasticsearch.cache.refresh.failures") + logger := logp.NewLogger("agentcfg") return &ElasticsearchFetcher{ client: client, @@ -96,6 +108,14 @@ func NewElasticsearchFetcher( logger: logger, rateLimitedLogger: logger.WithOptions(logs.WithRateLimit(loggerRateLimit)), tracer: tracer, + + esCacheEntriesCount: esCacheEntriesCount, + esFetchCount: esFetchCount, + esFetchFallbackCount: esFetchFallbackCount, + esFetchUnavailableCount: esFetchUnavailableCount, + esFetchInvalidCount: esFetchInvalidCount, + esCacheRefreshSuccesses: esCacheRefreshSuccesses, + esCacheRefreshFailures: esCacheRefreshFailures, } } @@ -105,22 +125,22 @@ func (f *ElasticsearchFetcher) Fetch(ctx context.Context, query Query) (Result, // Happy path: serve fetch requests using an initialized cache. f.mu.RLock() defer f.mu.RUnlock() - f.metrics.fetchES.Add(1) + f.esFetchCount.Add(ctx, 1) return matchAgentConfig(query, f.cache), nil } if f.fallbackFetcher != nil { - f.metrics.fetchFallback.Add(1) + f.esFetchFallbackCount.Add(ctx, 1) return f.fallbackFetcher.Fetch(ctx, query) } if f.invalidESCfg.Load() { - f.metrics.fetchInvalid.Add(1) + f.esFetchInvalidCount.Add(ctx, 1) f.rateLimitedLogger.Errorf("rejecting fetch request: no valid elasticsearch config") return Result{}, errors.New(ErrNoValidElasticsearchConfig) } - f.metrics.fetchFallbackUnavailable.Add(1) + f.esFetchUnavailableCount.Add(ctx, 1) f.rateLimitedLogger.Warnf("rejecting fetch request: infrastructure is not ready") return Result{}, errors.New(ErrInfrastructureNotReady) } @@ -213,15 +233,16 @@ func (f *ElasticsearchFetcher) refreshCache(ctx context.Context) (err error) { defer func() { if err != nil { - f.metrics.cacheRefreshFailures.Add(1) + f.esCacheRefreshFailures.Add(ctx, 1) } else { - f.metrics.cacheRefreshSuccesses.Add(1) + f.esCacheRefreshSuccesses.Add(ctx, 1) } }() for { result, err := f.singlePageRefresh(ctx, scrollID) if err != nil { + f.clearScroll(ctx, scrollID) return err } @@ -240,15 +261,33 @@ func (f *ElasticsearchFetcher) refreshCache(ctx context.Context) (err error) { } } + f.clearScroll(ctx, scrollID) + f.mu.Lock() f.cache = buffer f.mu.Unlock() f.cacheInitialized.Store(true) - f.metrics.cacheEntriesCount.Store(int64(len(f.cache))) + f.esCacheEntriesCount.Record(ctx, int64(len(f.cache))) f.last = time.Now() return nil } +func (f *ElasticsearchFetcher) clearScroll(ctx context.Context, scrollID string) { + resp, err := esapi.ClearScrollRequest{ + ScrollID: []string{scrollID}, + }.Do(ctx, f.client) + if err != nil { + f.logger.Warnf("failed to clear scroll: %v", err) + return + } + + if resp.IsError() { + f.logger.Warnf("clearscroll request returned error: %s", resp.Status()) + } + + resp.Body.Close() +} + func (f *ElasticsearchFetcher) singlePageRefresh(ctx context.Context, scrollID string) (cacheResult, error) { var result cacheResult var err error @@ -285,20 +324,3 @@ func (f *ElasticsearchFetcher) singlePageRefresh(ctx context.Context, scrollID s } return result, json.NewDecoder(resp.Body).Decode(&result) } - -// CollectMonitoring may be called to collect monitoring metrics from the -// fetcher. It is intended to be used with libbeat/monitoring.NewFunc. -// -// The metrics should be added to the "apm-server.agentcfg.elasticsearch" registry. -func (f *ElasticsearchFetcher) CollectMonitoring(_ monitoring.Mode, V monitoring.Visitor) { - V.OnRegistryStart() - defer V.OnRegistryFinished() - - monitoring.ReportInt(V, "cache.entries.count", f.metrics.cacheEntriesCount.Load()) - monitoring.ReportInt(V, "fetch.es", f.metrics.fetchES.Load()) - monitoring.ReportInt(V, "fetch.fallback", f.metrics.fetchFallback.Load()) - monitoring.ReportInt(V, "fetch.unavailable", f.metrics.fetchFallbackUnavailable.Load()) - monitoring.ReportInt(V, "fetch.invalid", f.metrics.fetchInvalid.Load()) - monitoring.ReportInt(V, "cache.refresh.successes", f.metrics.cacheRefreshSuccesses.Load()) - monitoring.ReportInt(V, "cache.refresh.failures", f.metrics.cacheRefreshFailures.Load()) -} diff --git a/internal/agentcfg/elasticsearch_test.go b/internal/agentcfg/elasticsearch_test.go index 4671934c847..df86db50e26 100644 --- a/internal/agentcfg/elasticsearch_test.go +++ b/internal/agentcfg/elasticsearch_test.go @@ -22,6 +22,7 @@ import ( "encoding/json" "net/http" "net/http/httptest" + "strings" "testing" "time" @@ -29,6 +30,7 @@ import ( "github.com/stretchr/testify/require" "go.elastic.co/apm/v2" "go.elastic.co/apm/v2/apmtest" + "go.opentelemetry.io/otel/metric/noop" "github.com/elastic/apm-server/internal/elasticsearch" ) @@ -79,6 +81,11 @@ func newElasticsearchFetcher( i := 0 fetcher := NewElasticsearchFetcher(newMockElasticsearchClient(t, func(w http.ResponseWriter, r *http.Request) { + if r.Method == http.MethodDelete && strings.HasPrefix(r.URL.Path, "/_search/scroll") { + scrollID := strings.TrimPrefix(r.URL.Path, "/_search/scroll/") + assert.Equal(t, respTmpl["_scroll_id"], scrollID) + return + } switch r.URL.Path { case "/_search/scroll": scrollID := r.URL.Query().Get("scroll_id") @@ -98,7 +105,7 @@ func newElasticsearchFetcher( w.WriteHeader(200) w.Write(b) i += searchSize - }), time.Second, nil, rt) + }), time.Second, nil, rt, noop.NewMeterProvider()) fetcher.searchSize = searchSize return fetcher } @@ -117,14 +124,15 @@ func TestRun(t *testing.T) { assert.Eventually(t, func() bool { rt.Tracer.Flush(nil) payloads := rt.Payloads() - return len(payloads.Transactions) == 1 && len(payloads.Spans) == 3 + return len(payloads.Transactions) == 1 && len(payloads.Spans) == 4 }, 10*time.Second, 10*time.Millisecond) payloads := rt.Payloads() assert.Equal(t, "ElasticsearchFetcher.refresh", payloads.Transactions[0].Name) assert.Equal(t, "Elasticsearch: POST .apm-agent-configuration/_search", payloads.Spans[0].Name) assert.Equal(t, "Elasticsearch: POST _search/scroll", payloads.Spans[1].Name) - assert.Equal(t, "ElasticsearchFetcher.refreshCache", payloads.Spans[2].Name) + assert.Equal(t, "Elasticsearch: DELETE _search/scroll/", payloads.Spans[2].Name[:37]) // trim scrollID + assert.Equal(t, "ElasticsearchFetcher.refreshCache", payloads.Spans[3].Name) } func TestFetch(t *testing.T) { @@ -186,6 +194,7 @@ func TestFetchUseFallback(t *testing.T) { time.Second, fallbackFetcher, apmtest.NewRecordingTracer().Tracer, + noop.NewMeterProvider(), ) fetcher.refreshCache(context.Background()) @@ -201,6 +210,7 @@ func TestFetchNoFallbackInvalidESCfg(t *testing.T) { time.Second, nil, apmtest.NewRecordingTracer().Tracer, + noop.NewMeterProvider(), ) err := fetcher.refreshCache(context.Background()) @@ -217,6 +227,7 @@ func TestFetchNoFallback(t *testing.T) { time.Second, nil, apmtest.NewRecordingTracer().Tracer, + noop.NewMeterProvider(), ) err := fetcher.refreshCache(context.Background()) diff --git a/internal/agentcfg/fetch.go b/internal/agentcfg/fetch.go index f4792d16e96..a803184fdb0 100644 --- a/internal/agentcfg/fetch.go +++ b/internal/agentcfg/fetch.go @@ -17,38 +17,46 @@ package agentcfg -import ( - "context" - - "github.com/elastic/apm-server/internal/beater/config" -) - -// TransactionSamplingRateKey is the agent configuration key for the -// sampling rate. This is used by the Jaeger handler to adapt our agent -// configuration to the Jaeger remote sampler protocol. -const TransactionSamplingRateKey = "transaction_sample_rate" +import "context" // Fetcher defines a common interface to retrieving agent config. type Fetcher interface { Fetch(context.Context, Query) (Result, error) } -// DirectFetcher is an agent config fetcher which serves requests out of a -// statically defined set of agent configuration. These configurations are -// typically provided via Fleet. -type DirectFetcher struct { - cfgs []AgentConfig +// AgentConfig holds an agent configuration definition. +type AgentConfig struct { + // ServiceName holds the service name to which this agent configuration + // applies. This is optional. + ServiceName string + + // ServiceEnvironment holds the service environment to which this agent + // configuration applies. This is optional. + ServiceEnvironment string + + // AgentName holds the agent name to which this agent configuration + // applies. This is optional, and is used for filtering configuration + // settings for unauthenticated agents. + AgentName string + + // Etag holds a unique ID for the configuration, which agents + // will send along with their queries. The server uses this to + // determine whether agent configuration has been applied. + Etag string + + // Config holds configuration settings that should be sent to + // agents matching the above constraints. + Config map[string]string } -// NewDirectFetcher returns a new DirectFetcher that serves agent configuration -// requests using cfgs. -func NewDirectFetcher(cfgs []AgentConfig) *DirectFetcher { - return &DirectFetcher{cfgs} +func NewEmptyFetcher() Fetcher { + return &emptyFetcher{} } -// Fetch finds a matching AgentConfig in cfgs based on the received Query. -func (f *DirectFetcher) Fetch(_ context.Context, query Query) (Result, error) { - return matchAgentConfig(query, f.cfgs), nil +type emptyFetcher struct{} + +func (*emptyFetcher) Fetch(context.Context, Query) (Result, error) { + return zeroResult(), nil } // matchAgentConfig finds a matching AgentConfig based on the received Query. @@ -97,42 +105,3 @@ func matchAgentConfig(query Query, cfgs []AgentConfig) Result { } return result } - -// AgentConfig holds an agent configuration definition. -type AgentConfig struct { - // ServiceName holds the service name to which this agent configuration - // applies. This is optional. - ServiceName string - - // ServiceEnvironment holds the service environment to which this agent - // configuration applies. This is optional. - ServiceEnvironment string - - // AgentName holds the agent name to which this agent configuration - // applies. This is optional, and is used for filtering configuration - // settings for unauthenticated agents. - AgentName string - - // Etag holds a unique ID for the configuration, which agents - // will send along with their queries. The server uses this to - // determine whether agent configuration has been applied. - Etag string - - // Config holds configuration settings that should be sent to - // agents matching the above constraints. - Config map[string]string -} - -func ConvertAgentConfigs(fleetAgentConfigs []config.FleetAgentConfig) []AgentConfig { - agentConfigurations := make([]AgentConfig, len(fleetAgentConfigs)) - for i, in := range fleetAgentConfigs { - agentConfigurations[i] = AgentConfig{ - ServiceName: in.Service.Name, - ServiceEnvironment: in.Service.Environment, - AgentName: in.AgentName, - Etag: in.Etag, - Config: in.Config, - } - } - return agentConfigurations -} diff --git a/internal/agentcfg/fetch_test.go b/internal/agentcfg/fetch_test.go index 6c124572fc8..83e311f981f 100644 --- a/internal/agentcfg/fetch_test.go +++ b/internal/agentcfg/fetch_test.go @@ -18,12 +18,10 @@ package agentcfg import ( - "context" "testing" "time" "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" ) var ( @@ -38,214 +36,3 @@ func TestCustomJSON(t *testing.T) { actual, _ := newResult([]byte(input), nil) assert.Equal(t, expected, actual) } - -func TestDirectConfigurationPrecedence(t *testing.T) { - for _, tc := range []struct { - query Query - agentConfigs []AgentConfig - expectedSettings map[string]string - }{ - { - query: Query{ - Service: Service{ - Name: "service1", - Environment: "production", - }, - }, - agentConfigs: []AgentConfig{ - { - ServiceEnvironment: "production", - Config: map[string]string{"key1": "val2", "key2": "val2"}, - Etag: "def456", - }, - { - ServiceName: "service1", - Config: map[string]string{"key3": "val3"}, - Etag: "abc123", - }, - { - ServiceName: "service1", - ServiceEnvironment: "production", - Config: map[string]string{"key1": "val1"}, - Etag: "abc123", - }, - }, - expectedSettings: map[string]string{ - "key1": "val1", - }, - }, - { - query: Query{ - Service: Service{ - Name: "service1", - Environment: "production", - }, - }, - agentConfigs: []AgentConfig{ - { - ServiceEnvironment: "production", - Config: map[string]string{"key3": "val3"}, - Etag: "def456", - }, - { - ServiceName: "service1", - Config: map[string]string{"key1": "val1", "key2": "val2"}, - Etag: "abc123", - }, - }, - expectedSettings: map[string]string{ - "key1": "val1", - "key2": "val2", - }, - }, - { - query: Query{ - InsecureAgents: []string{"Jaeger"}, - Service: Service{ - Name: "service1", - Environment: "production", - }, - }, - agentConfigs: []AgentConfig{ - { - ServiceEnvironment: "production", - Config: map[string]string{"key3": "val3"}, - Etag: "def456", - }, - { - ServiceName: "service1", - Config: map[string]string{"key1": "val1", "key2": "val2"}, - Etag: "abc123", - }, - }, - expectedSettings: map[string]string{ - "key1": "val1", - "key2": "val2", - }, - }, - { - query: Query{ - InsecureAgents: []string{"Jaeger"}, - Service: Service{ - Name: "service1", - Environment: "production", - }, - }, - agentConfigs: []AgentConfig{ - { - ServiceEnvironment: "production", - Config: map[string]string{"key3": "val3"}, - Etag: "def456", - }, - { - ServiceName: "service1", - AgentName: "Jaeger/Python", - Config: map[string]string{"key1": "val1", "key2": "val2", "transaction_sample_rate": "0.1"}, - Etag: "abc123", - }, - }, - expectedSettings: map[string]string{ - "key1": "val1", - "key2": "val2", - "transaction_sample_rate": "0.1", - }, - }, - { - query: Query{ - Service: Service{ - Name: "service1", - Environment: "production", - }, - }, - agentConfigs: []AgentConfig{ - { - ServiceName: "service2", - Config: map[string]string{"key1": "val1", "key2": "val2"}, - Etag: "abc123", - }, - { - ServiceEnvironment: "production", - Config: map[string]string{"key3": "val3"}, - Etag: "def456", - }, - }, - expectedSettings: map[string]string{ - "key3": "val3", - }, - }, - { - query: Query{ - Service: Service{ - Name: "service1", - Environment: "production", - }, - }, - agentConfigs: []AgentConfig{ - { - ServiceName: "not-found", - Config: map[string]string{"key1": "val1"}, - Etag: "abc123", - }, - }, - expectedSettings: map[string]string{}, - }, - { - query: Query{ - Service: Service{ - Name: "service2", - Environment: "production", - }, - }, - agentConfigs: []AgentConfig{ - { - ServiceName: "service1", - Config: map[string]string{"key1": "val1", "key2": "val2"}, - Etag: "abc123", - }, - { - ServiceName: "service2", - Config: map[string]string{"key1": "val4", "key2": "val5"}, - Etag: "abc123", - }, - }, - expectedSettings: map[string]string{ - "key1": "val4", - "key2": "val5", - }, - }, - { - query: Query{ - Service: Service{ - Name: "service2", - Environment: "staging", - }, - }, - agentConfigs: []AgentConfig{ - { - ServiceName: "service1", - Config: map[string]string{"key1": "val1", "key2": "val2"}, - Etag: "abc123", - }, - { - ServiceEnvironment: "production", - Config: map[string]string{"key1": "val4", "key2": "val5"}, - Etag: "abc123", - }, - { - Config: map[string]string{"key3": "val5", "key4": "val6"}, - Etag: "abc123", - }, - }, - expectedSettings: map[string]string{ - "key3": "val5", - "key4": "val6", - }, - }, - } { - f := NewDirectFetcher(tc.agentConfigs) - result, err := f.Fetch(context.Background(), tc.query) - require.NoError(t, err) - - assert.Equal(t, Settings(tc.expectedSettings), result.Source.Settings) - } -} diff --git a/internal/beatcmd/apikey.go b/internal/beatcmd/apikey.go deleted file mode 100644 index f90b25af08b..00000000000 --- a/internal/beatcmd/apikey.go +++ /dev/null @@ -1,512 +0,0 @@ -// Licensed to Elasticsearch B.V. under one or more contributor -// license agreements. See the NOTICE file distributed with -// this work for additional information regarding copyright -// ownership. Elasticsearch B.V. licenses this file to you under -// the Apache License, Version 2.0 (the "License"); you may -// not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -package beatcmd - -import ( - "context" - "encoding/base64" - "encoding/json" - "errors" - "fmt" - "io" - "os" - "strings" - "time" - - "github.com/dustin/go-humanize" - "github.com/spf13/cobra" - - agentconfig "github.com/elastic/elastic-agent-libs/config" - - "github.com/elastic/apm-server/internal/beater/config" - "github.com/elastic/apm-server/internal/beater/headers" - - "github.com/elastic/apm-server/internal/beater/auth" - es "github.com/elastic/apm-server/internal/elasticsearch" -) - -const apikeyDeprecationNotice = `NOTE: "apm-server apikey" is deprecated, and will be removed in a future release. -See https://www.elastic.co/guide/en/apm/guide/current/api-key.html for managing API Keys.` - -func genApikeyCmd() *cobra.Command { - - short := "Manage API Keys for communication between APM agents and server (deprecated)" - apikeyCmd := cobra.Command{ - Use: "apikey", - Short: short, - Long: short + `. -Most operations require the "manage_api_key" cluster privilege. Ensure to configure "apm-server.api_key.*" or -"output.elasticsearch.*" appropriately. APM Server will create security privileges for the "apm" application; -you can freely query them. If you modify or delete apm privileges, APM Server might reject all requests. -Check the Elastic Security API documentation for details. - -` + apikeyDeprecationNotice, - } - - apikeyCmd.AddCommand( - createApikeyCmd(), - invalidateApikeyCmd(), - getApikeysCmd(), - verifyApikeyCmd(), - ) - return &apikeyCmd -} - -func createApikeyCmd() *cobra.Command { - var keyName, expiration string - var ingest, sourcemap, agentConfig, json bool - short := "Create an API Key with the specified privilege(s)" - create := &cobra.Command{ - Use: "create", - Short: short, - Long: short + `. -If no privilege(s) are specified, the API Key will be valid for all.`, - Run: makeAPIKeyRun(&json, func(client *es.Client, config *config.Config, args []string) error { - privileges := booleansToPrivileges(ingest, sourcemap, agentConfig) - if len(privileges) == 0 { - // No privileges specified, grant all. - privileges = auth.AllPrivilegeActions() - } - return createAPIKey(client, keyName, expiration, privileges, json) - }), - } - create.Flags().StringVar(&keyName, "name", "apm-key", "API Key name") - create.Flags().StringVar(&expiration, "expiration", "", - `expiration for the key, eg. "1d" (default never)`) - create.Flags().BoolVar(&ingest, "ingest", false, - fmt.Sprintf("give the %v privilege to this key, required for ingesting events", auth.PrivilegeEventWrite)) - create.Flags().BoolVar(&sourcemap, "sourcemap", false, - fmt.Sprintf("give the %v privilege to this key, required for uploading sourcemaps", - auth.PrivilegeSourcemapWrite)) - create.Flags().BoolVar(&agentConfig, "agent-config", false, - fmt.Sprintf("give the %v privilege to this key, required for agents to read configuration remotely", - auth.PrivilegeAgentConfigRead)) - create.Flags().BoolVar(&json, "json", false, - "prints the output of this command as JSON") - // this actually means "preserve sorting given in code" and not reorder them alphabetically - create.Flags().SortFlags = false - return create -} - -func invalidateApikeyCmd() *cobra.Command { - var id, name string - var json bool - short := "Invalidate API Key(s) by Id or Name" - invalidate := &cobra.Command{ - Use: "invalidate", - Short: short, - Long: short + `. -If both "id" and "name" are supplied, only "id" will be used. -If neither of them are, an error will be returned.`, - Run: makeAPIKeyRun(&json, func(client *es.Client, config *config.Config, args []string) error { - if id == "" && name == "" { - // TODO(axw) this should trigger usage - return errors.New(`either "id" or "name" are required`) - } - return invalidateAPIKey(client, id, name, json) - }), - } - invalidate.Flags().StringVar(&id, "id", "", "id of the API Key to delete") - invalidate.Flags().StringVar(&name, "name", "", - "name of the API Key(s) to delete (several might match)") - invalidate.Flags().BoolVar(&json, "json", false, - "prints the output of this command as JSON") - invalidate.Flags().SortFlags = false - return invalidate -} - -func getApikeysCmd() *cobra.Command { - var id, name string - var validOnly, json bool - short := "Query API Key(s) by Id or Name" - info := &cobra.Command{ - Use: "info", - Short: short, - Long: short + `. -If both "id" and "name" are supplied, only "id" will be used. -If neither of them are, an error will be returned.`, - Run: makeAPIKeyRun(&json, func(client *es.Client, config *config.Config, args []string) error { - if id == "" && name == "" { - // TODO(axw) this should trigger usage - return errors.New(`either "id" or "name" are required`) - } - return getAPIKey(client, &id, &name, validOnly, json) - }), - } - info.Flags().StringVar(&id, "id", "", "id of the API Key to query") - info.Flags().StringVar(&name, "name", "", - "name of the API Key(s) to query (several might match)") - info.Flags().BoolVar(&validOnly, "valid-only", false, - "only return valid API Keys (not expired or invalidated)") - info.Flags().BoolVar(&json, "json", false, - "prints the output of this command as JSON") - info.Flags().SortFlags = false - return info -} - -func verifyApikeyCmd() *cobra.Command { - var credentials string - var ingest, sourcemap, agentConfig, json bool - short := `Check if a "credentials" string has the given privilege(s)` - long := short + `. -If no privilege(s) are specified, the credentials will be queried for all.` - verify := &cobra.Command{ - Use: "verify", - Short: short, - Long: long, - Run: makeAPIKeyRun(&json, func(client *es.Client, config *config.Config, args []string) error { - privileges := booleansToPrivileges(ingest, sourcemap, agentConfig) - if len(privileges) == 0 { - privileges = auth.AllPrivilegeActions() - } - return verifyAPIKey(config, privileges, credentials, json) - }), - } - verify.Flags().StringVar(&credentials, "credentials", "", `credentials for which check privileges (required)`) - verify.Flags().BoolVar(&ingest, "ingest", false, - fmt.Sprintf("ask for the %v privilege, required for ingesting events", auth.PrivilegeEventWrite)) - verify.Flags().BoolVar(&sourcemap, "sourcemap", false, - fmt.Sprintf("ask for the %v privilege, required for uploading sourcemaps", - auth.PrivilegeSourcemapWrite)) - verify.Flags().BoolVar(&agentConfig, "agent-config", false, - fmt.Sprintf("ask for the %v privilege, required for agents to read configuration remotely", - auth.PrivilegeAgentConfigRead)) - verify.Flags().BoolVar(&json, "json", false, - "prints the output of this command as JSON") - verify.MarkFlagRequired("credentials") - verify.Flags().SortFlags = false - - return verify -} - -type apikeyRunFunc func(client *es.Client, config *config.Config, args []string) error - -type cobraRunFunc func(cmd *cobra.Command, args []string) - -func makeAPIKeyRun(json *bool, f apikeyRunFunc) cobraRunFunc { - return func(cmd *cobra.Command, args []string) { - var failed bool - client, config, err := bootstrap() - if err != nil { - failed = true - printErr(err, *json) - } else if err := f(client, config, args); err != nil { - failed = true - printErr(err, *json) - } - fmt.Fprintf(os.Stderr, "\n%s\n", apikeyDeprecationNotice) - if failed { - os.Exit(1) - } - } -} - -// apm-server.api_key.enabled is implicitly true -func bootstrap() (*es.Client, *config.Config, error) { - cfg, _, _, err := LoadConfig(WithMergeConfig( - agentconfig.MustNewConfigFrom(map[string]interface{}{ - "apm-server.auth.api_key.enabled": true, - }), - )) - if err != nil { - return nil, nil, err - } - - var esOutputCfg *agentconfig.C - if cfg.Output.Name() == "elasticsearch" { - esOutputCfg = cfg.Output.Config() - } - - beaterConfig, err := config.NewConfig(cfg.APMServer, esOutputCfg) - if err != nil { - return nil, nil, err - } - client, err := es.NewClient(beaterConfig.AgentAuth.APIKey.ESConfig) - if err != nil { - return nil, nil, err - } - return client, beaterConfig, nil -} - -func booleansToPrivileges(ingest, sourcemap, agentConfig bool) []es.PrivilegeAction { - privileges := make([]es.PrivilegeAction, 0) - if ingest { - privileges = append(privileges, auth.PrivilegeEventWrite.Action) - } - if sourcemap { - privileges = append(privileges, auth.PrivilegeSourcemapWrite.Action) - } - if agentConfig { - privileges = append(privileges, auth.PrivilegeAgentConfigRead.Action) - } - return privileges -} - -func createAPIKey(client *es.Client, keyName, expiry string, privileges []es.PrivilegeAction, asJSON bool) error { - - // Elasticsearch will allow a user without the right apm privileges to create API keys, but the keys won't validate - // check first whether the user has the right privileges, and bail out early if not - // is not possible to always do it automatically, because file-based users and roles are not queryable - hasPrivileges, err := es.HasPrivileges(context.Background(), client, es.HasPrivilegesRequest{ - Applications: []es.Application{ - { - Name: auth.Application, - Privileges: privileges, - Resources: []es.Resource{auth.ResourceInternal}, - }, - }, - }, "") - if err != nil { - return err - } - if !hasPrivileges.HasAll { - var missingPrivileges []string - for action, hasPrivilege := range hasPrivileges.Application[auth.Application][auth.ResourceInternal] { - if !hasPrivilege { - missingPrivileges = append(missingPrivileges, string(action)) - } - } - return fmt.Errorf(`%s is missing the following requested privilege(s): %s. - -You might try with the superuser, or add the APM application privileges to the role of the authenticated user, eg.: -PUT /_security/role/my_role { - ... - "applications": [{ - "application": "apm", - "privileges": ["sourcemap:write", "event:write", "config_agent:read"], - "resources": ["*"] - }], - ... -} - `, hasPrivileges.Username, strings.Join(missingPrivileges, ", ")) - } - - printText, printJSON := printers(asJSON) - - apikeyRequest := es.CreateAPIKeyRequest{ - Name: keyName, - RoleDescriptors: es.RoleDescriptor{ - auth.Application: es.Applications{ - Applications: []es.Application{ - { - Name: auth.Application, - Privileges: privileges, - Resources: []es.Resource{"*"}, - }, - }, - }, - }, - Metadata: map[string]interface{}{"application": "apm"}, - } - if expiry != "" { - apikeyRequest.Expiration = &expiry - } - - response, err := es.CreateAPIKey(context.Background(), client, apikeyRequest) - if err != nil { - return err - } - - type APIKey struct { - es.CreateAPIKeyResponse - Credentials string `json:"credentials"` - } - apikey := APIKey{ - CreateAPIKeyResponse: response, - Credentials: base64.StdEncoding.EncodeToString([]byte(response.ID + ":" + response.Key)), - } - - printText("API Key created:") - printText("") - printText("Name ........... %s", apikey.Name) - printText("Expiration ..... %s", humanTime(apikey.ExpirationMs)) - printText("Id ............. %s", apikey.ID) - printText("API Key ........ %s (won't be shown again)", apikey.Key) - printText(`Credentials .... %s (use it as "Authorization: APIKey " header to communicate with APM Server, won't be shown again)`, apikey.Credentials) - - printJSON(apikey) - return nil -} - -func getAPIKey(client *es.Client, id, name *string, validOnly, asJSON bool) error { - if isSet(id) { - name = nil - } else if isSet(name) { - id = nil - } - request := es.GetAPIKeyRequest{ - APIKeyQuery: es.APIKeyQuery{ - ID: id, - Name: name, - }, - } - - apikeys, err := es.GetAPIKeys(context.Background(), client, request) - if err != nil { - return err - } - - transform := es.GetAPIKeyResponse{APIKeys: make([]es.APIKeyResponse, 0)} - printText, printJSON := printers(asJSON) - for _, apikey := range apikeys.APIKeys { - expiry := humanTime(apikey.ExpirationMs) - if validOnly && (apikey.Invalidated || expiry == "expired") { - continue - } - creation := time.Unix(apikey.Creation/1000, 0).Format("2006-02-01 15:04") - printText("Username ....... %s", apikey.Username) - printText("Api Key Name ... %s", apikey.Name) - printText("Id ............. %s", apikey.ID) - printText("Creation ....... %s", creation) - printText("Invalidated .... %t", apikey.Invalidated) - if !apikey.Invalidated { - printText("Expiration ..... %s", expiry) - } - printText("") - transform.APIKeys = append(transform.APIKeys, apikey) - } - printText("%d API Keys found", len(transform.APIKeys)) - printJSON(transform) - return nil -} - -func invalidateAPIKey(client *es.Client, id string, name string, asJSON bool) error { - invalidateKeysRequest := es.InvalidateAPIKeyRequest{} - if id != "" { - invalidateKeysRequest.IDs = []string{id} - } else if name != "" { - invalidateKeysRequest.Name = &name - } - invalidation, err := es.InvalidateAPIKey(context.Background(), client, invalidateKeysRequest) - if err != nil { - return err - } - - printText, printJSON := printers(asJSON) - printText("Invalidated keys ... %s", strings.Join(invalidation.Invalidated, ", ")) - printText("Error count ........ %d", invalidation.ErrorCount) - printJSON(invalidation) - return nil -} - -func verifyAPIKey(config *config.Config, privileges []es.PrivilegeAction, credentials string, asJSON bool) error { - authenticator, err := auth.NewAuthenticator(config.AgentAuth) - if err != nil { - return err - } - _, authz, err := authenticator.Authenticate(context.Background(), headers.APIKey, credentials) - if err != nil { - return err - } - perms := make(es.Permissions) - printText, printJSON := printers(asJSON) - for _, privilege := range privileges { - var action auth.Action - switch privilege { - case auth.PrivilegeAgentConfigRead.Action: - action = auth.ActionAgentConfig - case auth.PrivilegeEventWrite.Action: - action = auth.ActionEventIngest - case auth.PrivilegeSourcemapWrite.Action: - action = auth.ActionSourcemapUpload - } - - authorized := true - if err := authz.Authorize(context.Background(), action, auth.Resource{}); err != nil { - if errors.Is(err, auth.ErrUnauthorized) { - authorized = false - } else { - return err - } - } - perms[privilege] = authorized - printText("Authorized for %s...: %s", humanPrivilege(privilege), humanBool(authorized)) - } - printJSON(perms) - return nil -} - -func humanBool(b bool) string { - if b { - return "Yes" - } - return "No" -} - -func humanPrivilege(privilege es.PrivilegeAction) string { - return fmt.Sprintf("privilege \"%v\"", privilege) -} - -func humanTime(millis *int64) string { - if millis == nil { - return "never" - } - expiry := time.Unix(*millis/1000, 0) - if !expiry.After(time.Now()) { - return "expired" - } - return humanize.Time(expiry) -} - -// returns 2 printers, one for text and one for JSON -// one of them will be a noop based on the boolean argument -func printers(b bool) (func(string, ...interface{}), func(interface{})) { - var w1 io.Writer = os.Stdout - var w2 = io.Discard - if b { - w1 = io.Discard - w2 = os.Stdout - } - return func(f string, i ...interface{}) { - fmt.Fprintf(w1, f, i...) - fmt.Fprintln(w1) - }, func(i interface{}) { - data, err := json.MarshalIndent(i, "", "\t") - if err != nil { - fmt.Fprintln(w2, err) - } - fmt.Fprintln(w2, string(data)) - } -} - -// prints an Elasticsearch error to stderr -func printErr(err error, asJSON bool) { - if asJSON { - var data []byte - var m map[string]interface{} - e := json.Unmarshal([]byte(err.Error()), &m) - if e == nil { - // err.Error() has JSON shape, likely coming from Elasticsearch - data, _ = json.MarshalIndent(m, "", "\t") - } else { - // err.Error() is a bare string, likely coming from apm-server - data, _ = json.MarshalIndent(struct { - Error string `json:"error"` - }{ - Error: err.Error(), - }, "", "\t") - } - fmt.Fprintln(os.Stdout, string(data)) - } else { - fmt.Fprintln(os.Stderr, err.Error()) - } -} - -func isSet(s *string) bool { - return s != nil && *s != "" -} diff --git a/internal/beatcmd/beat.go b/internal/beatcmd/beat.go index 8a62e1c8982..3970f85ec36 100644 --- a/internal/beatcmd/beat.go +++ b/internal/beatcmd/beat.go @@ -23,6 +23,7 @@ import ( "errors" "fmt" "io" + "log/slog" "os" "os/user" "runtime" @@ -31,8 +32,14 @@ import ( "strings" "time" - "github.com/gofrs/uuid" + "github.com/gofrs/uuid/v5" + "go.elastic.co/apm/module/apmotel/v2" + "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/attribute" + sdkmetric "go.opentelemetry.io/otel/sdk/metric" + "go.opentelemetry.io/otel/sdk/metric/metricdata" "go.uber.org/zap" + "go.uber.org/zap/exp/zapslog" "golang.org/x/sync/errgroup" "github.com/elastic/beats/v7/libbeat/api" @@ -74,6 +81,10 @@ type Beat struct { rawConfig *config.C newRunner NewRunnerFunc + + metricReader *sdkmetric.ManualReader + meterProvider *sdkmetric.MeterProvider + metricGatherer *apmotel.Gatherer } // BeatParams holds parameters for NewBeat. @@ -107,6 +118,18 @@ func NewBeat(args BeatParams) (*Beat, error) { beatName = hostname } + exporter, err := apmotel.NewGatherer() + if err != nil { + return nil, err + } + + metricReader := sdkmetric.NewManualReader() + meterProvider := sdkmetric.NewMeterProvider( + sdkmetric.WithReader(exporter), + sdkmetric.WithReader(metricReader), + ) + otel.SetMeterProvider(meterProvider) + eid := uuid.FromStringOrNil(metricreport.EphemeralID().String()) b := &Beat{ Beat: beat.Beat{ @@ -114,7 +137,7 @@ func NewBeat(args BeatParams) (*Beat, error) { Beat: "apm-server", ElasticLicensed: args.ElasticLicensed, IndexPrefix: "apm-server", - Version: version.Version, + Version: version.VersionWithQualifier(), Name: beatName, Hostname: hostname, StartTime: time.Now(), @@ -123,10 +146,14 @@ func NewBeat(args BeatParams) (*Beat, error) { Keystore: keystore, Config: &beat.BeatConfig{Output: cfg.Output}, BeatConfig: cfg.APMServer, + Registry: reload.NewRegistry(), }, - Config: cfg, - newRunner: args.NewRunner, - rawConfig: rawConfig, + Config: cfg, + newRunner: args.NewRunner, + rawConfig: rawConfig, + metricReader: metricReader, + meterProvider: meterProvider, + metricGatherer: &exporter, } if err := b.init(); err != nil { @@ -152,7 +179,7 @@ func (b *Beat) init() error { logp.Info("Beat ID: %v", b.Info.ID) // Initialize central config manager. - manager, err := management.NewManager(b.Config.Management, reload.RegisterV2) + manager, err := management.NewManager(b.Config.Management, b.Registry) if err != nil { return err } @@ -347,6 +374,11 @@ func (b *Beat) Run(ctx context.Context) error { return adjustMaxProcs(ctx, 30*time.Second, logger) }) + slogger := slog.New(zapslog.NewHandler(logger.Core())) + if err := adjustMemlimit(30*time.Second, slogger); err != nil { + return err + } + logSystemInfo(b.Info) cleanup, err := b.registerElasticsearchVersionCheck() @@ -366,7 +398,7 @@ func (b *Beat) Run(ctx context.Context) error { } if b.Manager.Enabled() { - reloader, err := NewReloader(b.Info, b.newRunner) + reloader, err := NewReloader(b.Info, b.Registry, b.newRunner, b.meterProvider, b.metricGatherer) if err != nil { return err } @@ -382,9 +414,11 @@ func (b *Beat) Run(ctx context.Context) error { return errors.New("no output defined, please define one under the output section") } runner, err := b.newRunner(RunnerParams{ - Config: b.rawConfig, - Info: b.Info, - Logger: logp.NewLogger(""), + Config: b.rawConfig, + Info: b.Info, + Logger: logp.NewLogger(""), + MeterProvider: b.meterProvider, + MetricsGatherer: b.metricGatherer, }) if err != nil { return err @@ -402,7 +436,12 @@ func (b *Beat) Run(ctx context.Context) error { // is then exposed through the HTTP monitoring endpoint (e.g. /info and /state) // and/or pushed to Elasticsearch through the x-pack monitoring feature. func (b *Beat) registerMetrics() { - // info + b.registerInfoMetrics() + b.registerStateMetrics() + b.registerStatsMetrics() +} + +func (b *Beat) registerInfoMetrics() { infoRegistry := monitoring.GetNamespace("info").GetRegistry() monitoring.NewString(infoRegistry, "version").Set(b.Info.Version) monitoring.NewString(infoRegistry, "beat").Set(b.Info.Beat) @@ -428,7 +467,9 @@ func (b *Beat) registerMetrics() { monitoring.NewString(infoRegistry, "gid").Set(u.Gid) } }() +} +func (b *Beat) registerStateMetrics() { stateRegistry := monitoring.GetNamespace("state").GetRegistry() // state.service @@ -449,6 +490,218 @@ func (b *Beat) registerMetrics() { monitoring.NewBool(managementRegistry, "enabled").Set(b.Manager.Enabled()) } +func (b *Beat) registerStatsMetrics() { + libbeatRegistry := monitoring.Default.GetRegistry("libbeat") + monitoring.NewFunc(libbeatRegistry, "output", func(_ monitoring.Mode, v monitoring.Visitor) { + var rm metricdata.ResourceMetrics + if err := b.metricReader.Collect(context.Background(), &rm); err != nil { + return + } + v.OnRegistryStart() + defer v.OnRegistryFinished() + for _, sm := range rm.ScopeMetrics { + switch { + case sm.Scope.Name == "github.com/elastic/go-docappender": + monitoring.ReportString(v, "type", "elasticsearch") + addDocappenderLibbeatOutputMetrics(context.Background(), v, sm) + } + } + }) + monitoring.NewFunc(libbeatRegistry, "pipeline", func(_ monitoring.Mode, v monitoring.Visitor) { + var rm metricdata.ResourceMetrics + if err := b.metricReader.Collect(context.Background(), &rm); err != nil { + return + } + v.OnRegistryStart() + defer v.OnRegistryFinished() + for _, sm := range rm.ScopeMetrics { + switch { + case sm.Scope.Name == "github.com/elastic/go-docappender": + addDocappenderLibbeatPipelineMetrics(context.Background(), v, sm) + } + } + }) + monitoring.NewFunc(monitoring.Default, "output.elasticsearch", func(_ monitoring.Mode, v monitoring.Visitor) { + var rm metricdata.ResourceMetrics + if err := b.metricReader.Collect(context.Background(), &rm); err != nil { + return + } + v.OnRegistryStart() + defer v.OnRegistryFinished() + for _, sm := range rm.ScopeMetrics { + switch { + case sm.Scope.Name == "github.com/elastic/go-docappender": + addDocappenderOutputElasticsearchMetrics(context.Background(), v, sm) + } + } + }) + monitoring.NewFunc(monitoring.Default, "apm-server", func(_ monitoring.Mode, v monitoring.Visitor) { + var rm metricdata.ResourceMetrics + if err := b.metricReader.Collect(context.Background(), &rm); err != nil { + return + } + v.OnRegistryStart() + defer v.OnRegistryFinished() + for _, sm := range rm.ScopeMetrics { + switch { + case strings.HasPrefix(sm.Scope.Name, "github.com/elastic/apm-server"): + // All simple scalar metrics that begin with the name "apm-server." + // in github.com/elastic/apm-server/... scopes are mapped directly. + addAPMServerMetrics(v, sm) + } + } + }) +} + +// getScalarInt64 returns a single-value, dimensionless +// gauge or counter integer value, or (0, false) if the +// data does not match these constraints. +func getScalarInt64(data metricdata.Aggregation) (int64, bool) { + switch data := data.(type) { + case metricdata.Sum[int64]: + if len(data.DataPoints) != 1 || data.DataPoints[0].Attributes.Len() != 0 { + break + } + return data.DataPoints[0].Value, true + case metricdata.Gauge[int64]: + if len(data.DataPoints) != 1 || data.DataPoints[0].Attributes.Len() != 0 { + break + } + return data.DataPoints[0].Value, true + } + return 0, false +} + +func addAPMServerMetrics(v monitoring.Visitor, sm metricdata.ScopeMetrics) { + for _, m := range sm.Metrics { + if suffix, ok := strings.CutPrefix(m.Name, "apm-server."); ok { + if value, ok := getScalarInt64(m.Data); ok { + keys := strings.Split(suffix, ".") + for i := 0; i < len(keys)-1; i++ { + v.OnRegistryStart() + v.OnKey(keys[i]) + } + monitoring.ReportInt(v, keys[len(keys)-1], value) + for i := 0; i < len(keys)-1; i++ { + v.OnRegistryFinished() + } + } + } + } +} + +// Adapt go-docappender's OTel metrics to beats stack monitoring metrics, +// with a mixture of libbeat-specific and apm-server specific metric names. +func addDocappenderLibbeatOutputMetrics(ctx context.Context, v monitoring.Visitor, sm metricdata.ScopeMetrics) { + var writeBytes int64 + + v.OnRegistryStart() + v.OnKey("events") + for _, m := range sm.Metrics { + switch m.Name { + case "elasticsearch.events.processed": + var acked, toomany, failed int64 + data, _ := m.Data.(metricdata.Sum[int64]) + for _, dp := range data.DataPoints { + status, ok := dp.Attributes.Value(attribute.Key("status")) + if !ok { + continue + } + switch status.AsString() { + case "Success": + acked += dp.Value + case "TooMany": + toomany += dp.Value + fallthrough + default: + failed += dp.Value + } + } + monitoring.ReportInt(v, "acked", acked) + monitoring.ReportInt(v, "failed", failed) + monitoring.ReportInt(v, "toomany", toomany) + case "elasticsearch.events.count": + if value, ok := getScalarInt64(m.Data); ok { + monitoring.ReportInt(v, "total", value) + } + case "elasticsearch.events.queued": + if value, ok := getScalarInt64(m.Data); ok { + monitoring.ReportInt(v, "active", value) + } + case "elasticsearch.flushed.bytes": + if value, ok := getScalarInt64(m.Data); ok { + writeBytes = value + } + case "elasticsearch.bulk_requests.count": + if value, ok := getScalarInt64(m.Data); ok { + monitoring.ReportInt(v, "batches", value) + } + } + } + v.OnRegistryFinished() + + if writeBytes > 0 { + v.OnRegistryStart() + v.OnKey("write") + monitoring.ReportInt(v, "bytes", writeBytes) + v.OnRegistryFinished() + } +} + +func addDocappenderLibbeatPipelineMetrics(ctx context.Context, v monitoring.Visitor, sm metricdata.ScopeMetrics) { + v.OnRegistryStart() + defer v.OnRegistryFinished() + v.OnKey("events") + + for _, m := range sm.Metrics { + switch m.Name { + case "elasticsearch.events.count": + if value, ok := getScalarInt64(m.Data); ok { + monitoring.ReportInt(v, "total", value) + } + } + } +} + +// Add non-libbeat Elasticsearch output metrics under "output.elasticsearch". +func addDocappenderOutputElasticsearchMetrics(ctx context.Context, v monitoring.Visitor, sm metricdata.ScopeMetrics) { + var bulkRequestsCount, bulkRequestsAvailable int64 + var indexersCreated, indexersDestroyed int64 + for _, m := range sm.Metrics { + switch m.Name { + case "elasticsearch.bulk_requests.count": + if value, ok := getScalarInt64(m.Data); ok { + bulkRequestsCount = value + } + case "elasticsearch.bulk_requests.available": + if value, ok := getScalarInt64(m.Data); ok { + bulkRequestsAvailable = value + } + case "elasticsearch.indexer.created": + if value, ok := getScalarInt64(m.Data); ok { + indexersCreated = value + } + case "elasticsearch.indexer.destroyed": + if value, ok := getScalarInt64(m.Data); ok { + indexersDestroyed = value + } + } + } + + v.OnRegistryStart() + v.OnKey("bulk_requests") + monitoring.ReportInt(v, "completed", bulkRequestsCount) + monitoring.ReportInt(v, "available", bulkRequestsAvailable) + v.OnRegistryFinished() + + v.OnRegistryStart() + v.OnKey("indexers") + monitoring.ReportInt(v, "created", indexersCreated) + monitoring.ReportInt(v, "destroyed", indexersDestroyed) + monitoring.ReportInt(v, "active", indexersCreated-indexersDestroyed+1) + v.OnRegistryFinished() +} + // registerElasticsearchVerfication registers a global callback to make sure // the Elasticsearch instance we are connecting to has a valid license, and is // at least on the same version as APM Server. diff --git a/internal/beatcmd/beat_test.go b/internal/beatcmd/beat_test.go index 2599647fc21..abb5822da68 100644 --- a/internal/beatcmd/beat_test.go +++ b/internal/beatcmd/beat_test.go @@ -19,23 +19,38 @@ package beatcmd import ( "context" + "encoding/json" + "errors" "fmt" + "net/http" "os" "strconv" + "strings" + "sync/atomic" "testing" "time" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "golang.org/x/sync/errgroup" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" "github.com/elastic/apm-server/internal/version" + "github.com/elastic/beats/v7/libbeat/beat" "github.com/elastic/beats/v7/libbeat/common/reload" "github.com/elastic/beats/v7/libbeat/management" + "github.com/elastic/beats/v7/libbeat/tests/integration" + xpacklbmanagement "github.com/elastic/beats/v7/x-pack/libbeat/management" + "github.com/elastic/elastic-agent-client/v7/pkg/client" + "github.com/elastic/elastic-agent-client/v7/pkg/proto" "github.com/elastic/elastic-agent-libs/config" "github.com/elastic/elastic-agent-libs/logp" "github.com/elastic/elastic-agent-libs/monitoring" "github.com/elastic/elastic-agent-libs/paths" + "github.com/elastic/go-docappender/v2" + "github.com/elastic/go-docappender/v2/docappendertest" + "github.com/elastic/go-elasticsearch/v8/esutil" ) // TestRunMaxProcs ensures Beat.Run calls the GOMAXPROCS adjustment code by looking for log messages. @@ -84,7 +99,7 @@ func TestRunnerParams(t *testing.T) { assert.NoError(t, stop()) assert.Equal(t, "apm-server", args.Info.Beat) - assert.Equal(t, version.Version, args.Info.Version) + assert.Equal(t, version.VersionWithQualifier(), args.Info.Version) assert.True(t, args.Info.ElasticLicensed) assert.Equal(t, "my-custom-name", b.Beat.Info.Name) assert.NotZero(t, args.Info.ID) @@ -116,6 +131,141 @@ func TestRunnerParams(t *testing.T) { }, m) } +// TestLibbeatMetrics tests the mapping of go-docappender OTel +// metrics to legacy libbeat monitoring metrics. +func TestLibbeatMetrics(t *testing.T) { + runnerParamsChan := make(chan RunnerParams, 1) + beat := newBeat(t, "output.elasticsearch.enabled: true", func(args RunnerParams) (Runner, error) { + runnerParamsChan <- args + return runnerFunc(func(ctx context.Context) error { + <-ctx.Done() + return ctx.Err() + }), nil + }) + stop := runBeat(t, beat) + defer func() { assert.NoError(t, stop()) }() + args := <-runnerParamsChan + + var requestIndex atomic.Int64 + requestsChan := make(chan chan struct{}) + defer close(requestsChan) + esClient := docappendertest.NewMockElasticsearchClient(t, func(w http.ResponseWriter, r *http.Request) { + select { + case <-r.Context().Done(): + return + case ch := <-requestsChan: + select { + case <-r.Context().Done(): + return + case <-ch: + } + } + _, result := docappendertest.DecodeBulkRequest(r) + switch requestIndex.Add(1) { + case 2: + result.HasErrors = true + result.Items[0]["create"] = esutil.BulkIndexerResponseItem{Status: 400} + case 4: + result.HasErrors = true + result.Items[0]["create"] = esutil.BulkIndexerResponseItem{Status: 429} + default: + // success + } + json.NewEncoder(w).Encode(result) + }) + appender, err := docappender.New(esClient, docappender.Config{ + MeterProvider: args.MeterProvider, + FlushBytes: 1, + Scaling: docappender.ScalingConfig{ + ActiveRatio: 10, + IdleInterval: 100 * time.Millisecond, + ScaleUp: docappender.ScaleActionConfig{ + Threshold: 1, + CoolDown: time.Minute, + }, + }, + }) + require.NoError(t, err) + defer func() { + assert.NoError(t, appender.Close(context.Background())) + }() + + require.NoError(t, appender.Add(context.Background(), "index", strings.NewReader("{}"))) + require.NoError(t, appender.Add(context.Background(), "index", strings.NewReader("{}"))) + require.NoError(t, appender.Add(context.Background(), "index", strings.NewReader("{}"))) + require.NoError(t, appender.Add(context.Background(), "index", strings.NewReader("{}"))) + + libbeatRegistry := monitoring.Default.GetRegistry("libbeat") + snapshot := monitoring.CollectStructSnapshot(libbeatRegistry, monitoring.Full, false) + assert.Equal(t, map[string]any{ + "output": map[string]any{ + "type": "elasticsearch", + "events": map[string]any{ + "active": int64(4), + "total": int64(4), + }, + }, + "pipeline": map[string]any{ + "events": map[string]any{ + "total": int64(4), + }, + }, + }, snapshot) + + assert.Eventually(t, func() bool { + return appender.Stats().IndexersActive > 1 + }, 10*time.Second, 50*time.Millisecond) + + for i := 0; i < 4; i++ { + unblockRequest := make(chan struct{}) + requestsChan <- unblockRequest + unblockRequest <- struct{}{} + } + + assert.Eventually(t, func() bool { + snapshot = monitoring.CollectStructSnapshot(libbeatRegistry, monitoring.Full, false) + output := snapshot["output"].(map[string]any) + events := output["events"].(map[string]any) + return events["active"] == int64(0) + }, 10*time.Second, 100*time.Millisecond) + assert.Equal(t, map[string]any{ + "output": map[string]any{ + "type": "elasticsearch", + "events": map[string]any{ + "acked": int64(2), + "failed": int64(2), + "toomany": int64(1), + "active": int64(0), + "total": int64(4), + "batches": int64(4), + }, + "write": map[string]any{ + "bytes": int64(132), + }, + }, + "pipeline": map[string]any{ + "events": map[string]any{ + "total": int64(4), + }, + }, + }, snapshot) + + snapshot = monitoring.CollectStructSnapshot(monitoring.Default.GetRegistry("output"), monitoring.Full, false) + assert.Equal(t, map[string]any{ + "elasticsearch": map[string]any{ + "bulk_requests": map[string]any{ + "available": int64(10), + "completed": int64(4), + }, + "indexers": map[string]any{ + "active": int64(2), + "created": int64(1), + "destroyed": int64(0), + }, + }, + }, snapshot) +} + func TestUnmanagedOutputRequired(t *testing.T) { b := newBeat(t, "", func(args RunnerParams) (Runner, error) { panic("unreachable") @@ -125,10 +275,6 @@ func TestUnmanagedOutputRequired(t *testing.T) { } func TestRunManager(t *testing.T) { - oldRegistry := reload.RegisterV2 - defer func() { reload.RegisterV2 = oldRegistry }() - reload.RegisterV2 = reload.NewRegistry() - // Register our own mock management implementation. manager := newMockManager() management.SetManagerFactory(func(cfg *config.C, registry *reload.Registry) (management.Manager, error) { @@ -151,20 +297,20 @@ func TestRunManager(t *testing.T) { expectEvent(t, manager.started, "manager should have been started") expectNoEvent(t, manager.stopped, "manager should not have been stopped") - err := reload.RegisterV2.GetInputList().Reload([]*reload.ConfigWithMeta{{ + err := b.Registry.GetInputList().Reload([]*reload.ConfigWithMeta{{ Config: config.MustNewConfigFrom(`{ "revision": 1, "apm-server.host": "localhost:1234" }`), }}) assert.NoError(t, err) - err = reload.RegisterV2.GetReloadableOutput().Reload(&reload.ConfigWithMeta{ + err = b.Registry.GetReloadableOutput().Reload(&reload.ConfigWithMeta{ Config: config.MustNewConfigFrom(`{"console.enabled": true}`), }) assert.NoError(t, err) expectRunnerParams(t, calls) - err = reload.RegisterV2.GetReloadableAPM().Reload(&reload.ConfigWithMeta{ + err = b.Registry.GetReloadableAPM().Reload(&reload.ConfigWithMeta{ Config: config.MustNewConfigFrom(`{"elastic.enabled": true, "elastic.environment": "testenv"}`), }) assert.NoError(t, err) @@ -183,7 +329,7 @@ func TestRunManager(t *testing.T) { }, }, "instrumentation": map[string]interface{}{ - "enabled": false, + "enabled": true, "environment": "testenv", }, }, m) @@ -194,6 +340,232 @@ func TestRunManager(t *testing.T) { expectEvent(t, manager.stopped, "manager should have been stopped") } +func TestRunManager_Reloader(t *testing.T) { + // This test asserts that unit changes are reloaded correctly. + + finish := make(chan struct{}) + runCount := atomic.Int64{} + stopCount := atomic.Int64{} + + registry := reload.NewRegistry() + + reloader, err := NewReloader(beat.Info{}, registry, func(p RunnerParams) (Runner, error) { + return runnerFunc(func(ctx context.Context) error { + revision, err := p.Config.Int("revision", -1) + require.NoError(t, err) + if revision == 2 { + close(finish) + } + runCount.Add(1) + <-ctx.Done() + stopCount.Add(1) + return nil + }), nil + }, nil, nil) + require.NoError(t, err) + + agentInfo := &proto.AgentInfo{ + Id: "elastic-agent-id", + Version: version.VersionWithQualifier(), + Snapshot: true, + } + srv := integration.NewMockServer([]*proto.CheckinExpected{ + { + AgentInfo: agentInfo, + Units: []*proto.UnitExpected{ + { + Id: "output-unit", + Type: proto.UnitType_OUTPUT, + ConfigStateIdx: 1, + Config: &proto.UnitExpectedConfig{ + Id: "default", + Type: "elasticsearch", + Name: "elasticsearch", + }, + State: proto.State_HEALTHY, + LogLevel: proto.UnitLogLevel_INFO, + }, + { + Id: "input-unit-1", + Type: proto.UnitType_INPUT, + ConfigStateIdx: 1, + Config: &proto.UnitExpectedConfig{ + Id: "elastic-apm", + Type: "apm", + Name: "Elastic APM", + Streams: []*proto.Stream{ + { + Id: "elastic-apm", + Source: integration.RequireNewStruct(t, map[string]interface{}{ + "revision": 1, + }), + }, + }, + }, + State: proto.State_HEALTHY, + LogLevel: proto.UnitLogLevel_INFO, + }, + }, + Features: nil, + FeaturesIdx: 1, + }, + { + AgentInfo: agentInfo, + Units: []*proto.UnitExpected{ + { + Id: "output-unit", + Type: proto.UnitType_OUTPUT, + ConfigStateIdx: 1, + State: proto.State_HEALTHY, + LogLevel: proto.UnitLogLevel_INFO, + }, + { + Id: "elastic-apm", + Type: proto.UnitType_INPUT, + ConfigStateIdx: 2, + Config: &proto.UnitExpectedConfig{ + Id: "elastic-apm", + Type: "apm", + Name: "Elastic APM", + Streams: []*proto.Stream{ + { + Id: "elastic-apm", + Source: integration.RequireNewStruct(t, map[string]interface{}{ + "revision": 2, + }), + }, + }, + }, + State: proto.State_HEALTHY, + LogLevel: proto.UnitLogLevel_INFO, + }, + }, + Features: nil, + FeaturesIdx: 1, + }, + }, + nil, + 500*time.Millisecond, + ) + require.NoError(t, srv.Start()) + defer srv.Stop() + + client := client.NewV2( + fmt.Sprintf(":%d", srv.Port), + "", + client.VersionInfo{}, + client.WithGRPCDialOptions(grpc.WithTransportCredentials(insecure.NewCredentials()))) + manager, err := xpacklbmanagement.NewV2AgentManagerWithClient(&xpacklbmanagement.Config{ + Enabled: true, + }, registry, client) + require.NoError(t, err) + + err = manager.Start() + require.NoError(t, err) + defer manager.Stop() + + ctx, cancel := context.WithCancel(context.Background()) + go func() { + <-finish + cancel() + }() + err = reloader.Run(ctx) + require.NoError(t, err) + + assert.Eventually(t, func() bool { + return runCount.Load() == 2 && stopCount.Load() == 2 + }, 2*time.Second, 50*time.Millisecond) +} + +func TestRunManager_Reloader_newRunnerError(t *testing.T) { + // This test asserts that any errors when creating runner inside reloader, e.g. config parsing error, + // will cause the unit to fail. + + inputFailedMsg := make(chan string) + + registry := reload.NewRegistry() + + _, err := NewReloader(beat.Info{}, registry, func(_ RunnerParams) (Runner, error) { + return nil, errors.New("newRunner error") + }, nil, nil) + require.NoError(t, err) + + onObserved := func(observed *proto.CheckinObserved, currentIdx int) { + for _, unit := range observed.GetUnits() { + if unit.GetId() == "input-unit-1" && unit.GetState() == proto.State_FAILED { + inputFailedMsg <- unit.GetMessage() + } + } + } + agentInfo := &proto.AgentInfo{ + Id: "elastic-agent-id", + Version: version.VersionWithQualifier(), + Snapshot: true, + } + srv := integration.NewMockServer([]*proto.CheckinExpected{ + { + AgentInfo: agentInfo, + Units: []*proto.UnitExpected{ + { + Id: "output-unit", + Type: proto.UnitType_OUTPUT, + ConfigStateIdx: 1, + Config: &proto.UnitExpectedConfig{ + Id: "default", + Type: "elasticsearch", + Name: "elasticsearch", + }, + State: proto.State_HEALTHY, + LogLevel: proto.UnitLogLevel_INFO, + }, + { + Id: "input-unit-1", + Type: proto.UnitType_INPUT, + ConfigStateIdx: 1, + Config: &proto.UnitExpectedConfig{ + Id: "elastic-apm", + Type: "apm", + Name: "Elastic APM", + Streams: []*proto.Stream{ + { + Id: "elastic-apm", + Source: integration.RequireNewStruct(t, map[string]interface{}{ + "revision": 1, + }), + }, + }, + }, + State: proto.State_HEALTHY, + LogLevel: proto.UnitLogLevel_INFO, + }, + }, + Features: nil, + FeaturesIdx: 1, + }, + }, + onObserved, + 500*time.Millisecond, + ) + require.NoError(t, srv.Start()) + defer srv.Stop() + + client := client.NewV2( + fmt.Sprintf(":%d", srv.Port), + "", + client.VersionInfo{}, + client.WithGRPCDialOptions(grpc.WithTransportCredentials(insecure.NewCredentials()))) + manager, err := xpacklbmanagement.NewV2AgentManagerWithClient(&xpacklbmanagement.Config{ + Enabled: true, + }, registry, client) + require.NoError(t, err) + + err = manager.Start() + require.NoError(t, err) + defer manager.Stop() + + assert.Equal(t, "failed to load input config: newRunner error", <-inputFailedMsg) +} + func runBeat(t testing.TB, beat *Beat) (stop func() error) { ctx, cancel := context.WithCancel(context.Background()) g, ctx := errgroup.WithContext(ctx) @@ -230,15 +602,12 @@ func resetGlobals() { // Clear monitoring registries to allow the new Beat to populate them. monitoring.GetNamespace("info").SetRegistry(nil) monitoring.GetNamespace("state").SetRegistry(nil) - for _, name := range []string{"system", "beat", "libbeat"} { + for _, name := range []string{"system", "beat", "libbeat", "apm-server", "output"} { registry := monitoring.Default.GetRegistry(name) if registry != nil { registry.Clear() } } - - // Create a new reload registry, as the Beat.Run method will register with it. - reload.RegisterV2 = reload.NewRegistry() } type runnerFunc func(ctx context.Context) error diff --git a/internal/beatcmd/cmd.go b/internal/beatcmd/cmd.go index a312ebecdf4..10ee94b966a 100644 --- a/internal/beatcmd/cmd.go +++ b/internal/beatcmd/cmd.go @@ -20,12 +20,10 @@ package beatcmd import ( "flag" "fmt" - "os" "github.com/spf13/cobra" "github.com/elastic/beats/v7/libbeat/cfgfile" - "github.com/elastic/beats/v7/libbeat/cmd/platformcheck" "github.com/elastic/elastic-agent-libs/logp" ) @@ -34,11 +32,6 @@ import ( // NewRootCommand takes a BeatParams, which will be passed to // commands that must create an instance of APM Server. func NewRootCommand(beatParams BeatParams) *cobra.Command { - if err := platformcheck.CheckNativePlatformCompat(); err != nil { - fmt.Fprintf(os.Stderr, "Failed to initialize: %v\n", err) - os.Exit(1) - } - err := cfgfile.ChangeDefaultCfgfileFlag("apm-server") if err != nil { panic(fmt.Errorf("failed to set default config file path: %v", err)) @@ -47,8 +40,11 @@ func NewRootCommand(beatParams BeatParams) *cobra.Command { // root command is an alias for "run" runCommand := genRunCmd(beatParams) rootCommand := &cobra.Command{ - Use: "apm-server", - RunE: runCommand.RunE, + Use: "apm-server", + RunE: func(cmd *cobra.Command, args []string) error { + cfgfile.HandleFlags() + return runCommand.RunE(cmd, args) + }, CompletionOptions: cobra.CompletionOptions{ DisableDefaultCmd: true, }, @@ -81,7 +77,6 @@ func NewRootCommand(beatParams BeatParams) *cobra.Command { rootCommand.AddCommand(keystoreCommand) rootCommand.AddCommand(versionCommand) rootCommand.AddCommand(genTestCmd(beatParams)) - rootCommand.AddCommand(genApikeyCmd()) return rootCommand } diff --git a/internal/beatcmd/init.go b/internal/beatcmd/init.go index bbf657006ac..cb7a339311d 100644 --- a/internal/beatcmd/init.go +++ b/internal/beatcmd/init.go @@ -19,12 +19,9 @@ package beatcmd import ( cryptorand "crypto/rand" - "log" "math" "math/big" "math/rand" - "os" - "strings" "time" "github.com/elastic/beats/v7/libbeat/cfgfile" @@ -55,14 +52,5 @@ func initRand() { } func initFlags() { - // For backwards compatibility, convert -flags to --flags. - for i, arg := range os.Args[1:] { - if strings.HasPrefix(arg, "-") && !strings.HasPrefix(arg, "--") && len(arg) > 2 { - os.Args[1+i] = "-" + arg - } - } - - if err := cfgfile.HandleFlags(); err != nil { - log.Fatal(err) - } + cfgfile.Initialize() } diff --git a/internal/beater/middleware/timeout_middleware.go b/internal/beatcmd/memlimit.go similarity index 52% rename from internal/beater/middleware/timeout_middleware.go rename to internal/beatcmd/memlimit.go index abd91a301e9..d813fca4956 100644 --- a/internal/beater/middleware/timeout_middleware.go +++ b/internal/beatcmd/memlimit.go @@ -15,31 +15,29 @@ // specific language governing permissions and limitations // under the License. -package middleware +package beatcmd import ( - "context" + "fmt" + "log/slog" + "time" - "github.com/pkg/errors" - - "github.com/elastic/apm-server/internal/beater/request" + "github.com/KimMachineGun/automemlimit/memlimit" ) -// TimeoutMiddleware assumes that a context.Canceled error indicates a timed out -// request. This could be caused by a either a client timeout or server timeout. -// The middleware sets the Context.Result. -func TimeoutMiddleware() Middleware { - tErr := errors.New("request timed out") - return func(h request.Handler) (request.Handler, error) { - return func(c *request.Context) { - h(c) - - err := c.Request.Context().Err() - if errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) { - c.Result.SetDefault(request.IDResponseErrorsTimeout) - c.Result.Err = tErr - c.Result.Body = tErr.Error() - } - }, nil +func adjustMemlimit(d time.Duration, logger *slog.Logger) error { + if _, err := memlimit.SetGoMemLimitWithOpts( + memlimit.WithProvider( + memlimit.ApplyFallback( + memlimit.FromCgroup, + memlimit.FromSystem, + ), + ), + memlimit.WithLogger(logger), + memlimit.WithRefreshInterval(d), + memlimit.WithRatio(0.9), + ); err != nil { + return fmt.Errorf("failed to set go memlimit: %w", err) } + return nil } diff --git a/internal/beatcmd/reloader.go b/internal/beatcmd/reloader.go index 297fa328cc9..3c416b02107 100644 --- a/internal/beatcmd/reloader.go +++ b/internal/beatcmd/reloader.go @@ -23,9 +23,13 @@ import ( "fmt" "sync" + "github.com/joeshaw/multierror" + "go.elastic.co/apm/module/apmotel/v2" + "go.opentelemetry.io/otel/metric" "golang.org/x/sync/errgroup" "github.com/elastic/beats/v7/libbeat/beat" + "github.com/elastic/beats/v7/libbeat/cfgfile" "github.com/elastic/beats/v7/libbeat/common/reload" "github.com/elastic/elastic-agent-libs/config" "github.com/elastic/elastic-agent-libs/logp" @@ -48,6 +52,19 @@ type RunnerParams struct { // Logger holds a logger to use for logging throughout the APM Server. Logger *logp.Logger + + // MeterProvider holds a metric.MeterProvider that can be used for + // creating metrics. The same MeterProvider is expected to be used + // for each instance of the Runner, to ensure counter metrics are + // not reset. + // + // NOTE(axw) metrics registered through this provider are used for + // feeding into both Elastic APM (if enabled) and the libbeat + // monitoring framework. For the latter, only gauge and counter + // metrics are supported, and attributes (dimensions) are ignored. + MeterProvider metric.MeterProvider + + MetricsGatherer *apmotel.Gatherer } // Runner is an interface returned by NewRunnerFunc. @@ -58,20 +75,23 @@ type Runner interface { // NewReloader returns a new Reloader which creates Runners using the provided // beat.Info and NewRunnerFunc. -func NewReloader(info beat.Info, newRunner NewRunnerFunc) (*Reloader, error) { +func NewReloader(info beat.Info, registry *reload.Registry, newRunner NewRunnerFunc, meterProvider metric.MeterProvider, metricGatherer *apmotel.Gatherer) (*Reloader, error) { r := &Reloader{ info: info, logger: logp.NewLogger(""), newRunner: newRunner, stopped: make(chan struct{}), + + meterProvider: meterProvider, + metricGatherer: metricGatherer, } - if err := reload.RegisterV2.RegisterList(reload.InputRegName, reloadableListFunc(r.reloadInputs)); err != nil { + if err := registry.RegisterList(reload.InputRegName, reloadableListFunc(r.reloadInputs)); err != nil { return nil, fmt.Errorf("failed to register inputs reloader: %w", err) } - if err := reload.RegisterV2.Register(reload.OutputRegName, reload.ReloadableFunc(r.reloadOutput)); err != nil { + if err := registry.Register(reload.OutputRegName, reload.ReloadableFunc(r.reloadOutput)); err != nil { return nil, fmt.Errorf("failed to register output reloader: %w", err) } - if err := reload.RegisterV2.Register(reload.APMRegName, reload.ReloadableFunc(r.reloadAPMTracing)); err != nil { + if err := registry.Register(reload.APMRegName, reload.ReloadableFunc(r.reloadAPMTracing)); err != nil { return nil, fmt.Errorf("failed to register apm tracing reloader: %w", err) } return r, nil @@ -84,6 +104,9 @@ type Reloader struct { logger *logp.Logger newRunner NewRunnerFunc + meterProvider metric.MeterProvider + metricGatherer *apmotel.Gatherer + runner Runner stopRunner func() error @@ -109,11 +132,21 @@ func (r *Reloader) Run(ctx context.Context) error { } // reloadInput (re)loads input configuration. +// It returns a *multierror.MultiError as libbeat manager error handling is tightly coupled +// with its own reloadable list implementation in libbeat/cfgfile/list.go. // // Note: reloadInputs may be called before the Reloader is running. func (r *Reloader) reloadInputs(configs []*reload.ConfigWithMeta) error { if n := len(configs); n != 1 { - return fmt.Errorf("only 1 input supported, got %d", n) + var errs multierror.Errors + for _, cfg := range configs { + unitErr := cfgfile.UnitError{ + Err: fmt.Errorf("only 1 input supported, got %d", n), + UnitID: cfg.InputUnitID, + } + errs = append(errs, unitErr) + } + return errs.Err() } r.mu.Lock() defer r.mu.Unlock() @@ -123,11 +156,21 @@ func (r *Reloader) reloadInputs(configs []*reload.ConfigWithMeta) error { // increasing revision number. revision, err := cfg.Int("revision", -1) if err != nil { - return fmt.Errorf("failed to extract input config revision: %w", err) + return multierror.Errors{ + cfgfile.UnitError{ + Err: fmt.Errorf("failed to extract input config revision: %w", err), + UnitID: configs[0].InputUnitID, + }, + }.Err() } if err := r.reload(cfg, r.outputConfig, r.apmTracingConfig); err != nil { - return fmt.Errorf("failed to load input config: %w", err) + return multierror.Errors{ + cfgfile.UnitError{ + Err: fmt.Errorf("failed to load input config: %w", err), + UnitID: configs[0].InputUnitID, + }, + }.Err() } r.inputConfig = cfg r.logger.With(logp.Int64("revision", revision)).Info("loaded input config") @@ -195,8 +238,7 @@ func (r *Reloader) reload(inputConfig, outputConfig, apmTracingConfig *config.C) return fmt.Errorf("APM tracing config for elastic not found") } // set enabled manually as APMConfig doesn't contain it. - // TODO set "enable" to true after the issue https://github.com/elastic/elastic-agent/issues/5211 gets resolved. - c.SetBool("enabled", -1, false) + c.SetBool("enabled", -1, true) wrappedApmTracingConfig = config.MustNewConfigFrom(map[string]interface{}{ "instrumentation": c, }) @@ -212,9 +254,11 @@ func (r *Reloader) reload(inputConfig, outputConfig, apmTracingConfig *config.C) // allow the runner to perform initialisations that must run // synchronously. newRunner, err := r.newRunner(RunnerParams{ - Config: mergedConfig, - Info: r.info, - Logger: r.logger, + Config: mergedConfig, + Info: r.info, + Logger: r.logger, + MeterProvider: r.meterProvider, + MetricsGatherer: r.metricGatherer, }) if err != nil { return err diff --git a/internal/beatcmd/reloader_test.go b/internal/beatcmd/reloader_test.go index 83a7fb38b6e..f496772b104 100644 --- a/internal/beatcmd/reloader_test.go +++ b/internal/beatcmd/reloader_test.go @@ -33,10 +33,6 @@ import ( ) func TestReloader(t *testing.T) { - oldRegistry := reload.RegisterV2 - defer func() { reload.RegisterV2 = oldRegistry }() - reload.RegisterV2 = reload.NewRegistry() - type runner struct { running chan struct{} stopped chan struct{} @@ -59,7 +55,9 @@ func TestReloader(t *testing.T) { panic("unreachable") } - reloader, err := NewReloader(beat.Info{}, func(args RunnerParams) (Runner, error) { + registry := reload.NewRegistry() + + reloader, err := NewReloader(beat.Info{}, registry, func(args RunnerParams) (Runner, error) { if shouldError, _ := args.Config.Bool("error", -1); shouldError { return nil, errors.New("no runner for you") } @@ -74,7 +72,7 @@ func TestReloader(t *testing.T) { <-ctx.Done() return nil }), nil - }) + }, nil, nil) require.NoError(t, err) ctx, cancel := context.WithCancel(context.Background()) @@ -86,29 +84,29 @@ func TestReloader(t *testing.T) { // No reload until there's input, output, apm tracing configuration. assertNoReload() - err = reload.RegisterV2.GetInputList().Reload([]*reload.ConfigWithMeta{{ + err = registry.GetInputList().Reload([]*reload.ConfigWithMeta{{ Config: config.MustNewConfigFrom(`{}`), }}) - assert.EqualError(t, err, "failed to extract input config revision: missing field accessing 'revision'") + assert.EqualError(t, err, "1 error: failed to extract input config revision: missing field accessing 'revision'") assertNoReload() - err = reload.RegisterV2.GetInputList().Reload([]*reload.ConfigWithMeta{{ + err = registry.GetInputList().Reload([]*reload.ConfigWithMeta{{ Config: config.MustNewConfigFrom(`{"revision": 1}`), }}) assert.NoError(t, err) assertNoReload() - err = reload.RegisterV2.GetReloadableOutput().Reload(&reload.ConfigWithMeta{ + err = registry.GetReloadableOutput().Reload(&reload.ConfigWithMeta{ Config: config.MustNewConfigFrom(`{}`), }) assert.NoError(t, err) assertNoReload() // an output must be set - err = reload.RegisterV2.GetReloadableAPM().Reload(nil) + err = registry.GetReloadableAPM().Reload(nil) assert.NoError(t, err) assertNoReload() - err = reload.RegisterV2.GetReloadableOutput().Reload(&reload.ConfigWithMeta{ + err = registry.GetReloadableOutput().Reload(&reload.ConfigWithMeta{ Config: config.MustNewConfigFrom(`{"console.enabled": true}`), }) assert.NoError(t, err) @@ -118,14 +116,14 @@ func TestReloader(t *testing.T) { expectEvent(t, r1.running, "runner should have been started") expectNoEvent(t, r1.stopped, "runner should not have been stopped") - err = reload.RegisterV2.GetInputList().Reload([]*reload.ConfigWithMeta{{ + err = registry.GetInputList().Reload([]*reload.ConfigWithMeta{{ Config: config.MustNewConfigFrom(`{"revision": 2, "error": true}`), }}) - assert.EqualError(t, err, "failed to load input config: no runner for you") + assert.EqualError(t, err, "1 error: failed to load input config: no runner for you") assertNoReload() // error occurred during reload, nothing changes expectNoEvent(t, r1.stopped, "runner should not have been stopped") - err = reload.RegisterV2.GetInputList().Reload([]*reload.ConfigWithMeta{{ + err = registry.GetInputList().Reload([]*reload.ConfigWithMeta{{ Config: config.MustNewConfigFrom(`{"revision": 3}`), }}) assert.NoError(t, err) @@ -134,7 +132,7 @@ func TestReloader(t *testing.T) { expectEvent(t, r2.running, "new runner should have been started") expectNoEvent(t, r2.stopped, "new runner should not have been stopped") - err = reload.RegisterV2.GetReloadableAPM().Reload(&reload.ConfigWithMeta{ + err = registry.GetReloadableAPM().Reload(&reload.ConfigWithMeta{ Config: config.MustNewConfigFrom(`{"elastic.enabled": true, "elastic.api_key": "boo"}`), }) assert.NoError(t, err) @@ -148,19 +146,17 @@ func TestReloader(t *testing.T) { } func TestReloaderNewRunnerParams(t *testing.T) { - oldRegistry := reload.RegisterV2 - defer func() { reload.RegisterV2 = oldRegistry }() - reload.RegisterV2 = reload.NewRegistry() + registry := reload.NewRegistry() calls := make(chan RunnerParams, 1) info := beat.Info{Beat: "not-apm-server", Version: "0.0.1"} - reloader, err := NewReloader(info, func(args RunnerParams) (Runner, error) { + reloader, err := NewReloader(info, registry, func(args RunnerParams) (Runner, error) { calls <- args return runnerFunc(func(ctx context.Context) error { <-ctx.Done() return nil }), nil - }) + }, nil, nil) require.NoError(t, err) ctx, cancel := context.WithCancel(context.Background()) @@ -169,24 +165,24 @@ func TestReloaderNewRunnerParams(t *testing.T) { defer func() { assert.NoError(t, g.Wait()) }() defer cancel() - reload.RegisterV2.GetInputList().Reload([]*reload.ConfigWithMeta{{ + registry.GetInputList().Reload([]*reload.ConfigWithMeta{{ Config: config.MustNewConfigFrom(`{"revision": 1, "input": 123}`), }}) // reloader will wait until input and output are available. // triggering APM reload before output reload will let the params to contain // the apm tracing config too in this test setup - reload.RegisterV2.GetReloadableAPM().Reload(&reload.ConfigWithMeta{ + registry.GetReloadableAPM().Reload(&reload.ConfigWithMeta{ Config: config.MustNewConfigFrom(`{"elastic.environment": "test"}`), }) - reload.RegisterV2.GetReloadableOutput().Reload(&reload.ConfigWithMeta{ + registry.GetReloadableOutput().Reload(&reload.ConfigWithMeta{ Config: config.MustNewConfigFrom(`{"console.enabled": true}`), }) args := <-calls assert.NotNil(t, args.Logger) assert.Equal(t, info, args.Info) - assert.Equal(t, config.MustNewConfigFrom(`{"revision": 1, "input": 123, "output.console.enabled": true, "instrumentation.enabled":false, "instrumentation.environment":"test"}`), args.Config) + assert.Equal(t, config.MustNewConfigFrom(`{"revision": 1, "input": 123, "output.console.enabled": true, "instrumentation.enabled":true, "instrumentation.environment":"test"}`), args.Config) } func expectNoEvent(t testing.TB, ch <-chan struct{}, message string) { diff --git a/internal/beatcmd/version.go b/internal/beatcmd/version.go index 29746ff2840..f3405ded4ac 100644 --- a/internal/beatcmd/version.go +++ b/internal/beatcmd/version.go @@ -41,7 +41,7 @@ var versionCommand = &cobra.Command{ fmt.Fprintf(cmd.OutOrStdout(), "apm-server version %s (%s/%s) [%s]\n", - version.Version, runtime.GOOS, runtime.GOARCH, + version.VersionWithQualifier(), runtime.GOOS, runtime.GOARCH, buf.String(), ) return nil diff --git a/internal/beater/api/config/agent/handler.go b/internal/beater/api/config/agent/handler.go index 1967123a93d..8faddc6a3b3 100644 --- a/internal/beater/api/config/agent/handler.go +++ b/internal/beater/api/config/agent/handler.go @@ -26,8 +26,6 @@ import ( "github.com/pkg/errors" - "github.com/elastic/elastic-agent-libs/monitoring" - "github.com/elastic/apm-server/internal/agentcfg" "github.com/elastic/apm-server/internal/beater/auth" "github.com/elastic/apm-server/internal/beater/headers" @@ -43,10 +41,6 @@ const ( ) var ( - // MonitoringMap holds a mapping for request.IDs to monitoring counters - MonitoringMap = request.DefaultMonitoringMapForRegistry(registry) - registry = monitoring.Default.NewRegistry("apm-server.acm") - errCacheControl = fmt.Sprintf("max-age=%v, must-revalidate", errMaxAgeDuration.Seconds()) ) diff --git a/internal/beater/api/config/agent/handler_test.go b/internal/beater/api/config/agent/handler_test.go index 8450bfebb64..c95417d73e3 100644 --- a/internal/beater/api/config/agent/handler_test.go +++ b/internal/beater/api/config/agent/handler_test.go @@ -231,23 +231,6 @@ func TestAgentConfigHandlerAuthorizedForService(t *testing.T) { assert.False(t, called) } -func TestConfigAgentHandler_DirectConfiguration(t *testing.T) { - fetcher := agentcfg.NewDirectFetcher([]agentcfg.AgentConfig{{ - ServiceName: "service1", - Config: map[string]string{"key1": "val1"}, - Etag: "abc123", - }}) - h := NewHandler(fetcher, time.Nanosecond, "", nil) - - w := sendRequest(h, httptest.NewRequest(http.MethodPost, "/config", jsonReader(map[string]interface{}{ - "service": map[string]interface{}{ - "name": "service1", - }, - }))) - assert.Equal(t, http.StatusOK, w.Code, w.Body.String()) - assert.JSONEq(t, `{"key1":"val1"}`, w.Body.String()) -} - func TestAgentConfigHandler_PostOk(t *testing.T) { f := newSanitizingKibanaFetcher(t, func(w http.ResponseWriter, r *http.Request) { fmt.Fprintln(w, `{"_id": "1", "_source": {"settings": {"sampling_rate": 0.5}}}`) diff --git a/internal/beater/api/intake/handler.go b/internal/beater/api/intake/handler.go index 4c64d5af54b..edfdcff660c 100644 --- a/internal/beater/api/intake/handler.go +++ b/internal/beater/api/intake/handler.go @@ -18,12 +18,13 @@ package intake import ( + "context" "errors" "fmt" "net/http" "strings" - "github.com/elastic/elastic-agent-libs/monitoring" + "go.opentelemetry.io/otel/metric" "github.com/elastic/apm-data/input/elasticapm" "github.com/elastic/apm-data/model/modelpb" @@ -39,15 +40,6 @@ const ( ) var ( - // MonitoringMap holds a mapping for request.IDs to monitoring counters - MonitoringMap = request.DefaultMonitoringMapForRegistry(registry) - registry = monitoring.Default.NewRegistry("apm-server.server") - - streamRegistry = monitoring.Default.NewRegistry("apm-server.processor.stream") - eventsAccepted = monitoring.NewInt(streamRegistry, "accepted") - eventsInvalid = monitoring.NewInt(streamRegistry, "errors.invalid") - eventsTooLarge = monitoring.NewInt(streamRegistry, "errors.toolarge") - errMethodNotAllowed = errors.New("only POST requests are supported") errServerShuttingDown = errors.New("server is shutting down") errInvalidContentType = errors.New("invalid content type") @@ -59,7 +51,12 @@ var ( type RequestMetadataFunc func(*request.Context) *modelpb.APMEvent // Handler returns a request.Handler for managing intake requests for backend and rum events. -func Handler(handler elasticapm.StreamHandler, requestMetadataFunc RequestMetadataFunc, batchProcessor modelpb.BatchProcessor) request.Handler { +func Handler(mp metric.MeterProvider, handler elasticapm.StreamHandler, requestMetadataFunc RequestMetadataFunc, batchProcessor modelpb.BatchProcessor) request.Handler { + meter := mp.Meter("github.com/elastic/apm-server/internal/beater/api/intake") + eventsAccepted, _ := meter.Int64Counter("apm-server.processor.stream.accepted") + eventsInvalid, _ := meter.Int64Counter("apm-server.processor.stream.errors.invalid") + eventsTooLarge, _ := meter.Int64Counter("apm-server.processor.stream.errors.toolarge") + return func(c *request.Context) { if err := validateRequest(c); err != nil { writeError(c, err) @@ -82,9 +79,9 @@ func Handler(handler elasticapm.StreamHandler, requestMetadataFunc RequestMetada batchProcessor, &result, ) - eventsAccepted.Add(int64(result.Accepted)) - eventsInvalid.Add(int64(result.Invalid)) - eventsTooLarge.Add(int64(result.TooLarge)) + eventsAccepted.Add(context.Background(), int64(result.Accepted)) + eventsInvalid.Add(context.Background(), int64(result.Invalid)) + eventsTooLarge.Add(context.Background(), int64(result.TooLarge)) writeStreamResult(c, result, err) } } diff --git a/internal/beater/api/intake/handler_test.go b/internal/beater/api/intake/handler_test.go index 4c52df49e83..3622ff9f6d0 100644 --- a/internal/beater/api/intake/handler_test.go +++ b/internal/beater/api/intake/handler_test.go @@ -32,12 +32,16 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "go.opentelemetry.io/otel/metric/noop" + sdkmetric "go.opentelemetry.io/otel/sdk/metric" + "go.opentelemetry.io/otel/sdk/metric/metricdata" "golang.org/x/sync/semaphore" "github.com/elastic/apm-data/input/elasticapm" "github.com/elastic/apm-data/model/modelpb" "github.com/elastic/apm-server/internal/beater/config" "github.com/elastic/apm-server/internal/beater/headers" + "github.com/elastic/apm-server/internal/beater/monitoringtest" "github.com/elastic/apm-server/internal/beater/request" "github.com/elastic/apm-server/internal/model/modelprocessor" "github.com/elastic/apm-server/internal/publish" @@ -141,7 +145,7 @@ func TestIntakeHandler(t *testing.T) { tc.setup(t) // call handler - h := Handler(tc.processor, emptyRequestMetadata, tc.batchProcessor) + h := Handler(noop.NewMeterProvider(), tc.processor, emptyRequestMetadata, tc.batchProcessor) h(tc.c) require.Equal(t, string(tc.id), string(tc.c.Result.ID)) @@ -163,10 +167,6 @@ func TestIntakeHandler(t *testing.T) { } func TestIntakeHandlerMonitoring(t *testing.T) { - eventsAccepted.Set(1) - eventsInvalid.Set(2) - eventsTooLarge.Set(3) - streamHandler := streamHandlerFunc(func( ctx context.Context, base *modelpb.APMEvent, @@ -181,15 +181,24 @@ func TestIntakeHandlerMonitoring(t *testing.T) { return errors.New("something bad happened at the end") }) - h := Handler(streamHandler, emptyRequestMetadata, modelprocessor.Nop{}) + reader := sdkmetric.NewManualReader(sdkmetric.WithTemporalitySelector( + func(ik sdkmetric.InstrumentKind) metricdata.Temporality { + return metricdata.DeltaTemporality + }, + )) + mp := sdkmetric.NewMeterProvider(sdkmetric.WithReader(reader)) + + h := Handler(mp, streamHandler, emptyRequestMetadata, modelprocessor.Nop{}) req := httptest.NewRequest("POST", "/", nil) c := request.NewContext() c.Reset(httptest.NewRecorder(), req) h(c) - assert.Equal(t, int64(11), eventsAccepted.Get()) - assert.Equal(t, int64(102), eventsInvalid.Get()) - assert.Equal(t, int64(1003), eventsTooLarge.Get()) + monitoringtest.ExpectOtelMetrics(t, reader, map[string]any{ + "apm-server.processor.stream.accepted": 10, + "apm-server.processor.stream.errors.invalid": 100, + "apm-server.processor.stream.errors.toolarge": 1000, + }) } func TestIntakeHandlerContentType(t *testing.T) { @@ -206,7 +215,7 @@ func TestIntakeHandlerContentType(t *testing.T) { } tc.setup(t) - h := Handler(tc.processor, emptyRequestMetadata, tc.batchProcessor) + h := Handler(noop.NewMeterProvider(), tc.processor, emptyRequestMetadata, tc.batchProcessor) h(tc.c) assert.Equal(t, tc.code, tc.w.Code, tc.c.Result.Err) } diff --git a/internal/beater/api/mux.go b/internal/beater/api/mux.go index a42b22f4a09..712bf933a70 100644 --- a/internal/beater/api/mux.go +++ b/internal/beater/api/mux.go @@ -25,10 +25,10 @@ import ( "github.com/gorilla/mux" "github.com/pkg/errors" + "go.opentelemetry.io/otel/metric" "go.uber.org/zap" "github.com/elastic/elastic-agent-libs/logp" - "github.com/elastic/elastic-agent-libs/monitoring" "github.com/elastic/apm-data/input" "github.com/elastic/apm-data/input/elasticapm" @@ -89,6 +89,7 @@ func NewMux( sourcemapFetcher sourcemap.Fetcher, publishReady func() bool, semaphore input.Semaphore, + meterProvider metric.MeterProvider, ) (*mux.Router, error) { pool := request.NewContextPool() logger := logp.NewLogger(logs.Handler) @@ -116,18 +117,18 @@ func NewMux( handlerFn func() (request.Handler, error) } - otlpHandlers := otlp.NewHTTPHandlers(zapLogger, batchProcessor, semaphore) - rumIntakeHandler := builder.rumIntakeHandler() + otlpHandlers := otlp.NewHTTPHandlers(zapLogger, batchProcessor, semaphore, meterProvider) + rumIntakeHandler := builder.rumIntakeHandler(meterProvider) routeMap := []route{ - {RootPath, builder.rootHandler(publishReady)}, - {AgentConfigPath, builder.backendAgentConfigHandler(fetcher)}, - {AgentConfigRUMPath, builder.rumAgentConfigHandler(fetcher)}, + {RootPath, builder.rootHandler(publishReady, meterProvider)}, + {AgentConfigPath, builder.backendAgentConfigHandler(fetcher, meterProvider)}, + {AgentConfigRUMPath, builder.rumAgentConfigHandler(fetcher, meterProvider)}, {IntakeRUMPath, rumIntakeHandler}, {IntakeRUMV3Path, rumIntakeHandler}, - {IntakePath, builder.backendIntakeHandler}, - {OTLPTracesIntakePath, builder.otlpHandler(otlpHandlers.HandleTraces, otlp.HTTPTracesMonitoringMap)}, - {OTLPMetricsIntakePath, builder.otlpHandler(otlpHandlers.HandleMetrics, otlp.HTTPMetricsMonitoringMap)}, - {OTLPLogsIntakePath, builder.otlpHandler(otlpHandlers.HandleLogs, otlp.HTTPLogsMonitoringMap)}, + {IntakePath, builder.backendIntakeHandler(meterProvider)}, + {OTLPTracesIntakePath, builder.otlpHandler(otlpHandlers.HandleTraces, "apm-server.otlp.http.traces.", meterProvider)}, + {OTLPMetricsIntakePath, builder.otlpHandler(otlpHandlers.HandleMetrics, "apm-server.otlp.http.metrics.", meterProvider)}, + {OTLPLogsIntakePath, builder.otlpHandler(otlpHandlers.HandleLogs, "apm-server.otlp.http.logs.", meterProvider)}, } for _, route := range routeMap { @@ -170,21 +171,23 @@ type routeBuilder struct { intakeSemaphore input.Semaphore } -func (r *routeBuilder) backendIntakeHandler() (request.Handler, error) { - h := intake.Handler(r.intakeProcessor, backendRequestMetadataFunc(r.cfg), r.batchProcessor) - return middleware.Wrap(h, backendMiddleware(r.cfg, r.authenticator, r.ratelimitStore, intake.MonitoringMap)...) +func (r *routeBuilder) backendIntakeHandler(mp metric.MeterProvider) func() (request.Handler, error) { + return func() (request.Handler, error) { + h := intake.Handler(mp, r.intakeProcessor, backendRequestMetadataFunc(r.cfg), r.batchProcessor) + return middleware.Wrap(h, backendMiddleware(r.cfg, r.authenticator, r.ratelimitStore, "apm-server.server.", mp)...) + } } -func (r *routeBuilder) otlpHandler(handler http.HandlerFunc, monitoringMap map[request.ResultID]*monitoring.Int) func() (request.Handler, error) { +func (r *routeBuilder) otlpHandler(handler http.HandlerFunc, metricsPrefix string, mp metric.MeterProvider) func() (request.Handler, error) { return func() (request.Handler, error) { h := func(c *request.Context) { handler(c.ResponseWriter, c.Request) } - return middleware.Wrap(h, backendMiddleware(r.cfg, r.authenticator, r.ratelimitStore, monitoringMap)...) + return middleware.Wrap(h, backendMiddleware(r.cfg, r.authenticator, r.ratelimitStore, metricsPrefix, mp)...) } } -func (r *routeBuilder) rumIntakeHandler() func() (request.Handler, error) { +func (r *routeBuilder) rumIntakeHandler(mp metric.MeterProvider) func() (request.Handler, error) { return func() (request.Handler, error) { var batchProcessors modelprocessor.Chained // The order of these processors is important. Source mapping must happen before identifying library frames, or @@ -214,34 +217,34 @@ func (r *routeBuilder) rumIntakeHandler() func() (request.Handler, error) { batchProcessors = append(batchProcessors, modelprocessor.SetCulprit{}) } batchProcessors = append(batchProcessors, r.batchProcessor) // r.batchProcessor always goes last - h := intake.Handler(r.intakeProcessor, rumRequestMetadataFunc(r.cfg), batchProcessors) - return middleware.Wrap(h, rumMiddleware(r.cfg, r.authenticator, r.ratelimitStore, intake.MonitoringMap)...) + h := intake.Handler(mp, r.intakeProcessor, rumRequestMetadataFunc(r.cfg), batchProcessors) + return middleware.Wrap(h, rumMiddleware(r.cfg, r.authenticator, r.ratelimitStore, "apm-server.server.", mp)...) } } -func (r *routeBuilder) rootHandler(publishReady func() bool) func() (request.Handler, error) { +func (r *routeBuilder) rootHandler(publishReady func() bool, mp metric.MeterProvider) func() (request.Handler, error) { return func() (request.Handler, error) { h := root.Handler(root.HandlerConfig{ - Version: version.Version, + Version: version.VersionWithQualifier(), PublishReady: publishReady, }) - return middleware.Wrap(h, rootMiddleware(r.cfg, r.authenticator)...) + return middleware.Wrap(h, rootMiddleware(r.cfg, r.authenticator, mp)...) } } -func (r *routeBuilder) backendAgentConfigHandler(f agentcfg.Fetcher) func() (request.Handler, error) { +func (r *routeBuilder) backendAgentConfigHandler(f agentcfg.Fetcher, mp metric.MeterProvider) func() (request.Handler, error) { return func() (request.Handler, error) { - return agentConfigHandler(r.cfg, r.authenticator, r.ratelimitStore, backendMiddleware, f) + return agentConfigHandler(r.cfg, r.authenticator, r.ratelimitStore, backendMiddleware, f, mp) } } -func (r *routeBuilder) rumAgentConfigHandler(f agentcfg.Fetcher) func() (request.Handler, error) { +func (r *routeBuilder) rumAgentConfigHandler(f agentcfg.Fetcher, mp metric.MeterProvider) func() (request.Handler, error) { return func() (request.Handler, error) { - return agentConfigHandler(r.cfg, r.authenticator, r.ratelimitStore, rumMiddleware, f) + return agentConfigHandler(r.cfg, r.authenticator, r.ratelimitStore, rumMiddleware, f, mp) } } -type middlewareFunc func(*config.Config, *auth.Authenticator, *ratelimit.Store, map[request.ResultID]*monitoring.Int) []middleware.Middleware +type middlewareFunc func(*config.Config, *auth.Authenticator, *ratelimit.Store, string, metric.MeterProvider) []middleware.Middleware func agentConfigHandler( cfg *config.Config, @@ -249,23 +252,23 @@ func agentConfigHandler( ratelimitStore *ratelimit.Store, middlewareFunc middlewareFunc, f agentcfg.Fetcher, + mp metric.MeterProvider, ) (request.Handler, error) { - mw := middlewareFunc(cfg, authenticator, ratelimitStore, agent.MonitoringMap) + mw := middlewareFunc(cfg, authenticator, ratelimitStore, "apm-server.acm.", mp) h := agent.NewHandler(f, cfg.AgentConfig.Cache.Expiration, cfg.DefaultServiceEnvironment, cfg.AgentAuth.Anonymous.AllowAgent) return middleware.Wrap(h, mw...) } -func apmMiddleware(m map[request.ResultID]*monitoring.Int) []middleware.Middleware { +func apmMiddleware(mp metric.MeterProvider, metricsPrefix string) []middleware.Middleware { return []middleware.Middleware{ middleware.LogMiddleware(), - middleware.TimeoutMiddleware(), middleware.RecoverPanicMiddleware(), - middleware.MonitoringMiddleware(m, nil), + middleware.MonitoringMiddleware(metricsPrefix, mp), } } -func backendMiddleware(cfg *config.Config, authenticator *auth.Authenticator, ratelimitStore *ratelimit.Store, m map[request.ResultID]*monitoring.Int) []middleware.Middleware { - backendMiddleware := append(apmMiddleware(m), +func backendMiddleware(cfg *config.Config, authenticator *auth.Authenticator, ratelimitStore *ratelimit.Store, metricsPrefix string, mp metric.MeterProvider) []middleware.Middleware { + backendMiddleware := append(apmMiddleware(mp, metricsPrefix), middleware.ResponseHeadersMiddleware(cfg.ResponseHeaders), middleware.AuthMiddleware(authenticator, true), middleware.AnonymousRateLimitMiddleware(ratelimitStore), @@ -273,11 +276,11 @@ func backendMiddleware(cfg *config.Config, authenticator *auth.Authenticator, ra return backendMiddleware } -func rumMiddleware(cfg *config.Config, authenticator *auth.Authenticator, ratelimitStore *ratelimit.Store, m map[request.ResultID]*monitoring.Int) []middleware.Middleware { +func rumMiddleware(cfg *config.Config, authenticator *auth.Authenticator, ratelimitStore *ratelimit.Store, metricsPrefix string, mp metric.MeterProvider) []middleware.Middleware { msg := "RUM endpoint is disabled. " + "Configure the `apm-server.rum` section in apm-server.yml to enable ingestion of RUM events. " + "If you are not using the RUM agent, you can safely ignore this error." - rumMiddleware := append(apmMiddleware(m), + rumMiddleware := append(apmMiddleware(mp, metricsPrefix), middleware.ResponseHeadersMiddleware(cfg.ResponseHeaders), middleware.ResponseHeadersMiddleware(cfg.RumConfig.ResponseHeaders), middleware.CORSMiddleware(cfg.RumConfig.AllowOrigins, cfg.RumConfig.AllowHeaders), @@ -287,8 +290,8 @@ func rumMiddleware(cfg *config.Config, authenticator *auth.Authenticator, rateli return append(rumMiddleware, middleware.KillSwitchMiddleware(cfg.RumConfig.Enabled, msg)) } -func rootMiddleware(cfg *config.Config, authenticator *auth.Authenticator) []middleware.Middleware { - return append(apmMiddleware(root.MonitoringMap), +func rootMiddleware(cfg *config.Config, authenticator *auth.Authenticator, mp metric.MeterProvider) []middleware.Middleware { + return append(apmMiddleware(mp, "apm-server.root."), middleware.ResponseHeadersMiddleware(cfg.ResponseHeaders), middleware.AuthMiddleware(authenticator, false), ) diff --git a/internal/beater/api/mux_config_agent_test.go b/internal/beater/api/mux_config_agent_test.go index 9adfe60661d..3a947c51b7b 100644 --- a/internal/beater/api/mux_config_agent_test.go +++ b/internal/beater/api/mux_config_agent_test.go @@ -24,7 +24,6 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/elastic/apm-server/internal/beater/api/config/agent" "github.com/elastic/apm-server/internal/beater/config" "github.com/elastic/apm-server/internal/beater/headers" "github.com/elastic/apm-server/internal/beater/request" @@ -61,11 +60,11 @@ func TestConfigAgentHandler_PanicMiddleware(t *testing.T) { } func TestConfigAgentHandler_MonitoringMiddleware(t *testing.T) { - testMonitoringMiddleware(t, "/config/v1/agents", agent.MonitoringMap, map[request.ResultID]int{ - request.IDRequestCount: 1, - request.IDResponseCount: 1, - request.IDResponseErrorsCount: 1, - request.IDResponseErrorsInvalidQuery: 1, + testMonitoringMiddleware(t, "/config/v1/agents", map[string]any{ + "http.server." + string(request.IDRequestCount): 1, + "http.server." + string(request.IDResponseCount): 1, + "http.server." + string(request.IDResponseErrorsCount): 1, + "http.server." + string(request.IDResponseErrorsInvalidQuery): 1, }) } diff --git a/internal/beater/api/mux_intake_backend_test.go b/internal/beater/api/mux_intake_backend_test.go index 1707582fa06..a2329bfa49a 100644 --- a/internal/beater/api/mux_intake_backend_test.go +++ b/internal/beater/api/mux_intake_backend_test.go @@ -25,7 +25,6 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/elastic/apm-server/internal/beater/api/intake" "github.com/elastic/apm-server/internal/beater/config" "github.com/elastic/apm-server/internal/beater/headers" "github.com/elastic/apm-server/internal/beater/request" @@ -66,11 +65,11 @@ func TestIntakeBackendHandler_PanicMiddleware(t *testing.T) { func TestIntakeBackendHandler_MonitoringMiddleware(t *testing.T) { // send GET request resulting in 405 MethodNotAllowed error - testMonitoringMiddleware(t, "/intake/v2/events", intake.MonitoringMap, map[request.ResultID]int{ - request.IDRequestCount: 1, - request.IDResponseCount: 1, - request.IDResponseErrorsCount: 1, - request.IDResponseErrorsMethodNotAllowed: 1, + testMonitoringMiddleware(t, "/intake/v2/events", map[string]any{ + "http.server." + string(request.IDRequestCount): 1, + "http.server." + string(request.IDResponseCount): 1, + "http.server." + string(request.IDResponseErrorsCount): 1, + "http.server." + string(request.IDResponseErrorsMethodNotAllowed): 1, }) } diff --git a/internal/beater/api/mux_intake_rum_test.go b/internal/beater/api/mux_intake_rum_test.go index f50f82d915a..977aea40ae9 100644 --- a/internal/beater/api/mux_intake_rum_test.go +++ b/internal/beater/api/mux_intake_rum_test.go @@ -25,8 +25,8 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "go.opentelemetry.io/otel/metric/noop" - "github.com/elastic/apm-server/internal/beater/api/intake" "github.com/elastic/apm-server/internal/beater/auth" "github.com/elastic/apm-server/internal/beater/config" "github.com/elastic/apm-server/internal/beater/headers" @@ -49,7 +49,7 @@ func TestOPTIONS(t *testing.T) { requestTaken <- struct{}{} <-done }, - rumMiddleware(cfg, authenticator, ratelimitStore, intake.MonitoringMap)...) + rumMiddleware(cfg, authenticator, ratelimitStore, "", noop.NewMeterProvider())...) // use this to block the single allowed concurrent requests go func() { @@ -99,7 +99,7 @@ func TestRUMHandler_KillSwitchMiddleware(t *testing.T) { func TestRUMHandler_CORSMiddleware(t *testing.T) { cfg := cfgEnabledRUM() cfg.RumConfig.AllowOrigins = []string{"foo"} - h := newTestMux(t, cfg) + h, _ := newTestMux(t, cfg) for _, path := range []string{"/intake/v2/rum/events", "/intake/v3/rum/events"} { req := httptest.NewRequest(http.MethodPost, path, nil) @@ -118,11 +118,11 @@ func TestIntakeRUMHandler_PanicMiddleware(t *testing.T) { func TestRumHandler_MonitoringMiddleware(t *testing.T) { // send GET request resulting in 403 Forbidden error for _, path := range []string{"/intake/v2/rum/events", "/intake/v3/rum/events"} { - testMonitoringMiddleware(t, path, intake.MonitoringMap, map[request.ResultID]int{ - request.IDRequestCount: 1, - request.IDResponseCount: 1, - request.IDResponseErrorsCount: 1, - request.IDResponseErrorsForbidden: 1, + testMonitoringMiddleware(t, path, map[string]any{ + "http.server." + string(request.IDRequestCount): 1, + "http.server." + string(request.IDResponseCount): 1, + "http.server." + string(request.IDResponseErrorsCount): 1, + "http.server." + string(request.IDResponseErrorsForbidden): 1, }) } } diff --git a/internal/beater/api/mux_root_test.go b/internal/beater/api/mux_root_test.go index b2b2fc1f013..2b2af7dcc47 100644 --- a/internal/beater/api/mux_root_test.go +++ b/internal/beater/api/mux_root_test.go @@ -25,7 +25,6 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/elastic/apm-server/internal/beater/api/root" "github.com/elastic/apm-server/internal/beater/config" "github.com/elastic/apm-server/internal/beater/headers" "github.com/elastic/apm-server/internal/beater/request" @@ -55,7 +54,7 @@ func TestRootHandler_AuthorizationMiddleware(t *testing.T) { } err = json.Unmarshal(rec.Body.Bytes(), &result) require.NoError(t, err) - assert.Equal(t, version.Version, result.Version) + assert.Equal(t, version.VersionWithQualifier(), result.Version) }) } @@ -64,10 +63,10 @@ func TestRootHandler_PanicMiddleware(t *testing.T) { } func TestRootHandler_MonitoringMiddleware(t *testing.T) { - testMonitoringMiddleware(t, "/", root.MonitoringMap, map[request.ResultID]int{ - request.IDRequestCount: 1, - request.IDResponseCount: 1, - request.IDResponseValidCount: 1, - request.IDResponseValidOK: 1, + testMonitoringMiddleware(t, "/", map[string]any{ + "http.server." + string(request.IDRequestCount): 1, + "http.server." + string(request.IDResponseCount): 1, + "http.server." + string(request.IDResponseValidCount): 1, + "http.server." + string(request.IDResponseValidOK): 1, }) } diff --git a/internal/beater/api/mux_test.go b/internal/beater/api/mux_test.go index ce0ca1d8f90..f4ee1e78c1e 100644 --- a/internal/beater/api/mux_test.go +++ b/internal/beater/api/mux_test.go @@ -29,6 +29,8 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + sdkmetric "go.opentelemetry.io/otel/sdk/metric" + "go.opentelemetry.io/otel/sdk/metric/metricdata" "golang.org/x/sync/semaphore" "github.com/elastic/apm-data/model/modelpb" @@ -39,7 +41,6 @@ import ( "github.com/elastic/apm-server/internal/beater/ratelimit" "github.com/elastic/apm-server/internal/beater/request" "github.com/elastic/apm-server/internal/sourcemap" - "github.com/elastic/elastic-agent-libs/monitoring" ) func TestBackendRequestMetadata(t *testing.T) { @@ -113,7 +114,7 @@ func requestToMuxerWithHeaderAndQueryString( } func requestToMuxer(cfg *config.Config, r *http.Request) (*httptest.ResponseRecorder, error) { - mux, err := muxBuilder{}.build(cfg) + _, mux, err := muxBuilder{}.build(cfg) if err != nil { return nil, err } @@ -123,7 +124,7 @@ func requestToMuxer(cfg *config.Config, r *http.Request) (*httptest.ResponseReco } func testPanicMiddleware(t *testing.T, urlPath string) { - h := newTestMux(t, config.DefaultConfig()) + h, _ := newTestMux(t, config.DefaultConfig()) req := httptest.NewRequest(http.MethodGet, urlPath, nil) var rec WriterPanicOnce @@ -133,21 +134,18 @@ func testPanicMiddleware(t *testing.T, urlPath string) { assert.JSONEq(t, `{"error":"panic handling request"}`, rec.Body.String()) } -func testMonitoringMiddleware(t *testing.T, urlPath string, monitoringMap map[request.ResultID]*monitoring.Int, expected map[request.ResultID]int) { - monitoringtest.ClearRegistry(monitoringMap) - - h := newTestMux(t, config.DefaultConfig()) +func testMonitoringMiddleware(t *testing.T, urlPath string, expectedMetrics map[string]any) { + h, reader := newTestMux(t, config.DefaultConfig()) req := httptest.NewRequest(http.MethodGet, urlPath, nil) h.ServeHTTP(httptest.NewRecorder(), req) - equal, result := monitoringtest.CompareMonitoringInt(expected, monitoringMap) - assert.True(t, equal, result) + monitoringtest.ExpectContainOtelMetrics(t, reader, expectedMetrics) } -func newTestMux(t *testing.T, cfg *config.Config) http.Handler { - mux, err := muxBuilder{}.build(cfg) +func newTestMux(t *testing.T, cfg *config.Config) (http.Handler, sdkmetric.Reader) { + reader, mux, err := muxBuilder{}.build(cfg) require.NoError(t, err) - return mux + return mux, reader } type muxBuilder struct { @@ -155,20 +153,29 @@ type muxBuilder struct { Managed bool } -func (m muxBuilder) build(cfg *config.Config) (http.Handler, error) { +func (m muxBuilder) build(cfg *config.Config) (sdkmetric.Reader, http.Handler, error) { + reader := sdkmetric.NewManualReader(sdkmetric.WithTemporalitySelector( + func(ik sdkmetric.InstrumentKind) metricdata.Temporality { + return metricdata.DeltaTemporality + }, + )) + mp := sdkmetric.NewMeterProvider(sdkmetric.WithReader(reader)) + nopBatchProcessor := modelpb.ProcessBatchFunc(func(context.Context, *modelpb.Batch) error { return nil }) ratelimitStore, _ := ratelimit.NewStore(1000, 1000, 1000) authenticator, _ := auth.NewAuthenticator(cfg.AgentAuth) - return NewMux( + r, err := NewMux( cfg, nopBatchProcessor, authenticator, - agentcfg.NewDirectFetcher(nil), + agentcfg.NewEmptyFetcher(), ratelimitStore, m.SourcemapFetcher, func() bool { return true }, semaphore.NewWeighted(1), + mp, ) + return reader, r, err } // WriterPanicOnce implements the http.ResponseWriter interface diff --git a/internal/beater/api/root/handler.go b/internal/beater/api/root/handler.go index ad12cf8ea43..2ef21a67bc4 100644 --- a/internal/beater/api/root/handler.go +++ b/internal/beater/api/root/handler.go @@ -22,18 +22,11 @@ import ( "github.com/elastic/beats/v7/libbeat/version" "github.com/elastic/elastic-agent-libs/mapstr" - "github.com/elastic/elastic-agent-libs/monitoring" "github.com/elastic/apm-server/internal/beater/auth" "github.com/elastic/apm-server/internal/beater/request" ) -var ( - // MonitoringMap holds a mapping for request.IDs to monitoring counters - MonitoringMap = request.DefaultMonitoringMapForRegistry(registry) - registry = monitoring.Default.NewRegistry("apm-server.root") -) - // HandlerConfig holds configuration for Handler. type HandlerConfig struct { // PublishReady reports whether or not the server is ready for publishing events. diff --git a/internal/beater/beater.go b/internal/beater/beater.go index 05549a5a45a..802f132e884 100644 --- a/internal/beater/beater.go +++ b/internal/beater/beater.go @@ -22,18 +22,21 @@ import ( "encoding/json" "errors" "fmt" + "hash" "net" "net/http" "os" "runtime" + "strconv" "time" + "github.com/cespare/xxhash/v2" "github.com/dustin/go-humanize" "go.elastic.co/apm/module/apmgrpc/v2" "go.elastic.co/apm/module/apmotel/v2" "go.elastic.co/apm/v2" "go.opentelemetry.io/otel" - "go.opentelemetry.io/otel/sdk/metric" + "go.opentelemetry.io/otel/metric" "go.uber.org/zap" "golang.org/x/sync/errgroup" "golang.org/x/sync/semaphore" @@ -71,11 +74,6 @@ import ( "github.com/elastic/apm-server/internal/version" ) -var ( - monitoringRegistry = monitoring.Default.NewRegistry("apm-server.sampling") - transactionsDroppedCounter = monitoring.NewInt(monitoringRegistry, "transactions_dropped") -) - // Runner initialises and runs and orchestrates the APM Server // HTTP and gRPC servers, event processing pipeline, and output. type Runner struct { @@ -87,7 +85,9 @@ type Runner struct { outputConfig agentconfig.Namespace elasticsearchOutputConfig *agentconfig.C - listener net.Listener + meterProvider metric.MeterProvider + metricGatherer *apmotel.Gatherer + listener net.Listener } // RunnerParams holds parameters for NewRunner. @@ -99,6 +99,13 @@ type RunnerParams struct { // Logger holds a logger to use for logging throughout the APM Server. Logger *logp.Logger + // MeterProvider holds a metric.MeterProvider that can be used for + // creating metrics. + MeterProvider metric.MeterProvider + + // MetricsGatherer holds an apmotel.Gatherer + MetricsGatherer *apmotel.Gatherer + // WrapServer holds an optional WrapServerFunc, for wrapping the // ServerParams and RunServerFunc used to run the APM Server. // @@ -147,7 +154,9 @@ func NewRunner(args RunnerParams) (*Runner, error) { outputConfig: unpackedConfig.Output, elasticsearchOutputConfig: elasticsearchOutputConfig, - listener: listener, + meterProvider: args.MeterProvider, + metricGatherer: args.MetricsGatherer, + listener: listener, }, nil } @@ -155,6 +164,7 @@ func NewRunner(args RunnerParams) (*Runner, error) { func (s *Runner) Run(ctx context.Context) error { defer s.listener.Close() g, ctx := errgroup.WithContext(ctx) + meter := s.meterProvider.Meter("github.com/elastic/apm-server/internal/beater") // backgroundContext is a context to use in operations that should // block until shutdown, and will be cancelled after the shutdown @@ -278,15 +288,7 @@ func (s *Runner) Run(ctx context.Context) error { } otel.SetTracerProvider(tracerProvider) - exporter, err := apmotel.NewGatherer() - if err != nil { - return err - } - meterProvider := metric.NewMeterProvider( - metric.WithReader(exporter), - ) - otel.SetMeterProvider(meterProvider) - tracer.RegisterMetricsGatherer(exporter) + tracer.RegisterMetricsGatherer(s.metricGatherer) // Ensure the libbeat output and go-elasticsearch clients do not index // any events to Elasticsearch before the integration is ready. @@ -355,7 +357,7 @@ func (s *Runner) Run(ctx context.Context) error { ratelimitStore, err := ratelimit.NewStore( s.config.AgentAuth.Anonymous.RateLimit.IPLimit, s.config.AgentAuth.Anonymous.RateLimit.EventLimit, - 3, // burst mulitiplier + 3, // burst multiplier ) if err != nil { return err @@ -368,7 +370,7 @@ func (s *Runner) Run(ctx context.Context) error { apmgrpc.NewUnaryServerInterceptor(apmgrpc.WithRecovery(), apmgrpc.WithTracer(tracer)), interceptors.ClientMetadata(), interceptors.Logging(gRPCLogger), - interceptors.Metrics(gRPCLogger, nil), + interceptors.Metrics(gRPCLogger, s.meterProvider), interceptors.Timeout(), interceptors.Auth(authenticator), interceptors.AnonymousRateLimit(ratelimitStore), @@ -382,13 +384,17 @@ func (s *Runner) Run(ctx context.Context) error { if err != nil { return err } + transactionsDroppedCounter, err := meter.Int64Counter("apm-server.sampling.transactions_dropped") + if err != nil { + return err + } batchProcessor := srvmodelprocessor.NewTracer("beater.ProcessBatch", modelprocessor.Chained{ // Ensure all events have observer.*, ecs.*, and data_stream.* fields added, // and are counted in metrics. This is done in the final processors to ensure // aggregated metrics are also processed. newObserverBatchProcessor(), &modelprocessor.SetDataStream{Namespace: s.config.DataStreams.Namespace}, - srvmodelprocessor.NewEventCounter(monitoring.Default.GetRegistry("apm-server")), + srvmodelprocessor.NewEventCounter(s.meterProvider), // The server always drops non-RUM unsampled transactions. We store RUM unsampled // transactions as they are needed by the User Experience app, which performs @@ -397,7 +403,7 @@ func (s *Runner) Run(ctx context.Context) error { // It is important that this is done just before calling the publisher to // avoid affecting aggregations. modelprocessor.NewDropUnsampled(false /* don't drop RUM unsampled transactions*/, func(i int64) { - transactionsDroppedCounter.Add(i) + transactionsDroppedCounter.Add(context.Background(), i) }), finalBatchProcessor, }) @@ -408,6 +414,7 @@ func (s *Runner) Run(ctx context.Context) error { kibanaClient, newElasticsearchClient, tracer, + s.meterProvider, ) if err != nil { return err @@ -433,6 +440,7 @@ func (s *Runner) Run(ctx context.Context) error { Namespace: s.config.DataStreams.Namespace, Logger: s.logger, Tracer: tracer, + MeterProvider: s.meterProvider, Authenticator: authenticator, RateLimitStore: ratelimitStore, BatchProcessor: batchProcessor, @@ -470,7 +478,11 @@ func (s *Runner) Run(ctx context.Context) error { // aggregation, sampling, and indexing. modelprocessor.SetHostHostname{}, modelprocessor.SetServiceNodeName{}, - modelprocessor.SetGroupingKey{}, + modelprocessor.SetGroupingKey{ + NewHash: func() hash.Hash { + return xxhash.New() + }, + }, modelprocessor.SetErrorMessage{}, } if s.config.DefaultServiceEnvironment != "" { @@ -485,7 +497,7 @@ func (s *Runner) Run(ctx context.Context) error { return runServer(ctx, serverParams) }) if tracerServerListener != nil { - tracerServer, err := newTracerServer(s.config, tracerServerListener, s.logger, serverParams.BatchProcessor, serverParams.Semaphore) + tracerServer, err := newTracerServer(s.config, tracerServerListener, s.logger, serverParams.BatchProcessor, serverParams.Semaphore, serverParams.MeterProvider) if err != nil { return fmt.Errorf("failed to create self-instrumentation server: %w", err) } @@ -525,11 +537,12 @@ func newInstrumentation(rawConfig *agentconfig.C) (instrumentation.Instrumentati ServerCertificate string `config:"servercert"` ServerCA string `config:"serverca"` } `config:"tls"` + SamplingRate *float32 `config:"samplingrate"` } cfg, err := rawConfig.Child("instrumentation", -1) if err != nil || !cfg.Enabled() { // Fallback to instrumentation.New if the configs are not present or disabled. - return instrumentation.New(rawConfig, "apm-server", version.Version) + return instrumentation.New(rawConfig, "apm-server", version.VersionWithQualifier()) } if err := cfg.Unpack(&apmCfg); err != nil { return nil, err @@ -541,6 +554,7 @@ func newInstrumentation(rawConfig *agentconfig.C) (instrumentation.Instrumentati envServerCert = "ELASTIC_APM_SERVER_CERT" envCACert = "ELASTIC_APM_SERVER_CA_CERT_FILE" envGlobalLabels = "ELASTIC_APM_GLOBAL_LABELS" + envSamplingRate = "ELASTIC_APM_TRANSACTION_SAMPLE_RATE" ) if apmCfg.APIKey != "" { os.Setenv(envAPIKey, apmCfg.APIKey) @@ -566,7 +580,12 @@ func newInstrumentation(rawConfig *agentconfig.C) (instrumentation.Instrumentati os.Setenv(envGlobalLabels, apmCfg.GlobalLabels) defer os.Unsetenv(envGlobalLabels) } - return instrumentation.New(rawConfig, "apm-server", version.Version) + if apmCfg.SamplingRate != nil { + r := max(min(*apmCfg.SamplingRate, 1.0), 0.0) + os.Setenv(envSamplingRate, strconv.FormatFloat(float64(r), 'f', -1, 32)) + defer os.Unsetenv(envSamplingRate) + } + return instrumentation.New(rawConfig, "apm-server", version.VersionWithQualifier()) } func maxConcurrentDecoders(memLimitGB float64) uint { @@ -665,9 +684,9 @@ func (s *Runner) newFinalBatchProcessor( newElasticsearchClient func(cfg *elasticsearch.Config) (*elasticsearch.Client, error), memLimit float64, ) (modelpb.BatchProcessor, func(context.Context) error, error) { - monitoring.Default.Remove("libbeat") - libbeatMonitoringRegistry := monitoring.Default.NewRegistry("libbeat") if s.elasticsearchOutputConfig == nil { + monitoring.Default.Remove("libbeat") + libbeatMonitoringRegistry := monitoring.Default.NewRegistry("libbeat") return s.newLibbeatFinalBatchProcessor(tracer, libbeatMonitoringRegistry) } @@ -681,7 +700,7 @@ func (s *Runner) newFinalBatchProcessor( monitoring.NewString(outputRegistry, "name").Set("elasticsearch") // Create the docappender and Elasticsearch config - appenderCfg, esCfg, err := s.newDocappenderConfig(tracer, memLimit) + appenderCfg, esCfg, err := s.newDocappenderConfig(tracer, s.meterProvider, memLimit) if err != nil { return nil, nil, err } @@ -694,65 +713,10 @@ func (s *Runner) newFinalBatchProcessor( return nil, nil, err } - // Install our own libbeat-compatible metrics callback which uses the docappender stats. - // All the metrics below are required to be reported to be able to display all relevant - // fields in the Stack Monitoring UI. - monitoring.NewFunc(libbeatMonitoringRegistry, "output.write", func(_ monitoring.Mode, v monitoring.Visitor) { - v.OnRegistryStart() - defer v.OnRegistryFinished() - v.OnKey("bytes") - v.OnInt(appender.Stats().BytesTotal) - }) - outputType := monitoring.NewString(libbeatMonitoringRegistry.GetRegistry("output"), "type") - outputType.Set("elasticsearch") - monitoring.NewFunc(libbeatMonitoringRegistry, "output.events", func(_ monitoring.Mode, v monitoring.Visitor) { - v.OnRegistryStart() - defer v.OnRegistryFinished() - stats := appender.Stats() - v.OnKey("acked") - v.OnInt(stats.Indexed) - v.OnKey("active") - v.OnInt(stats.Active) - v.OnKey("batches") - v.OnInt(stats.BulkRequests) - v.OnKey("failed") - v.OnInt(stats.Failed) - v.OnKey("toomany") - v.OnInt(stats.TooManyRequests) - v.OnKey("total") - v.OnInt(stats.Added) - }) - monitoring.NewFunc(libbeatMonitoringRegistry, "pipeline.events", func(_ monitoring.Mode, v monitoring.Visitor) { - v.OnRegistryStart() - defer v.OnRegistryFinished() - v.OnKey("total") - v.OnInt(appender.Stats().Added) - }) - monitoring.Default.Remove("output") - monitoring.NewFunc(monitoring.Default, "output.elasticsearch.bulk_requests", func(_ monitoring.Mode, v monitoring.Visitor) { - v.OnRegistryStart() - defer v.OnRegistryFinished() - stats := appender.Stats() - v.OnKey("available") - v.OnInt(stats.AvailableBulkRequests) - v.OnKey("completed") - v.OnInt(stats.BulkRequests) - }) - monitoring.NewFunc(monitoring.Default, "output.elasticsearch.indexers", func(_ monitoring.Mode, v monitoring.Visitor) { - v.OnRegistryStart() - defer v.OnRegistryFinished() - stats := appender.Stats() - v.OnKey("active") - v.OnInt(stats.IndexersActive) - v.OnKey("created") - v.OnInt(stats.IndexersCreated) - v.OnKey("destroyed") - v.OnInt(stats.IndexersDestroyed) - }) return newDocappenderBatchProcessor(appender), appender.Close, nil } -func (s *Runner) newDocappenderConfig(tracer *apm.Tracer, memLimit float64) ( +func (s *Runner) newDocappenderConfig(tracer *apm.Tracer, mp metric.MeterProvider, memLimit float64) ( docappender.Config, *elasticsearch.Config, error, ) { esConfig := struct { @@ -797,6 +761,7 @@ func (s *Runner) newDocappenderConfig(tracer *apm.Tracer, memLimit float64) ( FlushBytes: flushBytes, FlushInterval: esConfig.FlushInterval, Tracer: tracer, + MeterProvider: mp, MaxRequests: esConfig.MaxRequests, Scaling: scalingCfg, Logger: zap.New(s.logger.Core(), zap.WithCaller(true)), @@ -858,7 +823,7 @@ func (s *Runner) newLibbeatFinalBatchProcessor( beatInfo := beat.Info{ Beat: "apm-server", IndexPrefix: "apm-server", - Version: version.Version, + Version: version.VersionWithQualifier(), Hostname: hostname, Name: hostname, } diff --git a/internal/beater/beater_test.go b/internal/beater/beater_test.go index 289ef975303..70718244d16 100644 --- a/internal/beater/beater_test.go +++ b/internal/beater/beater_test.go @@ -24,10 +24,12 @@ import ( "encoding/pem" "errors" "fmt" + "io" "net/http" "net/http/httptest" "os" "path/filepath" + "strings" "testing" "time" @@ -183,7 +185,7 @@ func TestRunnerNewDocappenderConfig(t *testing.T) { elasticsearchOutputConfig: agentconfig.NewConfig(), logger: logp.NewLogger("test"), } - docCfg, esCfg, err := r.newDocappenderConfig(nil, c.memSize) + docCfg, esCfg, err := r.newDocappenderConfig(nil, nil, c.memSize) require.NoError(t, err) assert.Equal(t, docappender.Config{ Logger: zap.New(r.logger.Core(), zap.WithCaller(true)), @@ -215,7 +217,7 @@ func TestRunnerNewDocappenderConfig(t *testing.T) { }), logger: logp.NewLogger("test"), } - docCfg, esCfg, err := r.newDocappenderConfig(nil, c.memSize) + docCfg, esCfg, err := r.newDocappenderConfig(nil, nil, c.memSize) require.NoError(t, err) assert.Equal(t, docappender.Config{ Logger: zap.New(r.logger.Core(), zap.WithCaller(true)), @@ -285,6 +287,46 @@ func TestNewInstrumentation(t *testing.T) { assert.Equal(t, "Bearer secret", auth) } +func TestNewInstrumentationWithSampling(t *testing.T) { + runSampled := func(rate float32) { + var events int + s := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if r.URL.Path == "/intake/v2/events" { + zr, _ := zlib.NewReader(r.Body) + b, _ := io.ReadAll(zr) + // Skip metadata and transaction keys, only count span. + events = strings.Count(string(b), "\n") - 2 + } + w.WriteHeader(http.StatusOK) + })) + defer s.Close() + cfg := agentconfig.MustNewConfigFrom(map[string]interface{}{ + "instrumentation": map[string]interface{}{ + "enabled": true, + "hosts": []string{s.URL}, + "tls": map[string]interface{}{ + "skipverify": true, + }, + "samplingrate": fmt.Sprintf("%f", rate), + }, + }) + i, err := newInstrumentation(cfg) + require.NoError(t, err) + tracer := i.Tracer() + tr := tracer.StartTransaction("name", "type") + tr.StartSpan("span", "type", nil).End() + tr.End() + tracer.Flush(nil) + assert.Equal(t, int(rate), events) + } + t.Run("100% sampling", func(t *testing.T) { + runSampled(1.0) + }) + t.Run("0% sampling", func(t *testing.T) { + runSampled(0.0) + }) +} + func TestProcessMemoryLimit(t *testing.T) { l := logp.NewLogger("test") const gb = 1 << 30 diff --git a/internal/beater/beatertest/server.go b/internal/beater/beatertest/server.go index 9fc64c8fdf0..10eba224a71 100644 --- a/internal/beater/beatertest/server.go +++ b/internal/beater/beatertest/server.go @@ -28,6 +28,8 @@ import ( "time" "github.com/stretchr/testify/require" + "go.opentelemetry.io/otel/metric" + "go.opentelemetry.io/otel/metric/noop" "go.uber.org/zap" "go.uber.org/zap/zapcore" "go.uber.org/zap/zaptest/observer" @@ -88,6 +90,7 @@ func NewUnstartedServer(t testing.TB, opts ...option) *Server { "host": "localhost:0", }, })}, + meterProvider: noop.NewMeterProvider(), } for _, o := range opts { o(&options) @@ -111,9 +114,10 @@ func NewUnstartedServer(t testing.TB, opts ...option) *Server { } runner, err := beater.NewRunner(beater.RunnerParams{ - Config: cfg, - Logger: logger, - WrapServer: options.wrapServer, + Config: cfg, + Logger: logger, + WrapServer: options.wrapServer, + MeterProvider: options.meterProvider, }) require.NoError(t, err) @@ -190,8 +194,9 @@ func (s *Server) Close() error { } type options struct { - config []*agentconfig.C - wrapServer beater.WrapServerFunc + config []*agentconfig.C + wrapServer beater.WrapServerFunc + meterProvider metric.MeterProvider } type option func(*options) @@ -214,3 +219,10 @@ func WithWrapServer(wrapServer beater.WrapServerFunc) option { opts.wrapServer = wrapServer } } + +// WithMeterProvider is an option for setting a MeterProvider +func WithMeterProvider(mp metric.MeterProvider) option { + return func(opts *options) { + opts.meterProvider = mp + } +} diff --git a/internal/beater/config/agentconfig.go b/internal/beater/config/agentconfig.go index 55f22ed2c1d..3d3aa643f1c 100644 --- a/internal/beater/config/agentconfig.go +++ b/internal/beater/config/agentconfig.go @@ -18,9 +18,6 @@ package config import ( - "crypto/md5" - "encoding/json" - "fmt" "strings" "time" @@ -63,7 +60,7 @@ func (c *AgentConfig) Unpack(in *config.C) error { } func (c *AgentConfig) setup(log *logp.Logger, outputESCfg *config.C) error { - if float64(int(c.Cache.Expiration.Seconds())) != c.Cache.Expiration.Seconds() { + if c.Cache.Expiration%time.Second != 0 { return errors.New(msgInvalidConfigAgentCfg) } if outputESCfg != nil { @@ -106,30 +103,6 @@ func defaultAgentConfig() AgentConfig { } } -// FleetAgentConfig defines configuration for agents. -type FleetAgentConfig struct { - Service Service `config:"service"` - AgentName string `config:"agent.name"` - Etag string `config:"etag"` - Config map[string]string -} - -func (s *FleetAgentConfig) setup() error { - if s.Config == nil { - // Config may be passed to APM Server as `null` when no attributes - // are defined in an APM Agent central configuration entry. - s.Config = make(map[string]string) - } - if s.Etag == "" { - m, err := json.Marshal(s) - if err != nil { - return fmt.Errorf("error generating etag for %s: %v", s.Service, err) - } - s.Etag = fmt.Sprintf("%x", md5.Sum(m)) - } - return nil -} - // Service defines a unique way of identifying a running agent. type Service struct { Name string `config:"name"` diff --git a/internal/beater/config/agentconfig_test.go b/internal/beater/config/agentconfig_test.go index 94d66701bb6..23b004f6b36 100644 --- a/internal/beater/config/agentconfig_test.go +++ b/internal/beater/config/agentconfig_test.go @@ -47,18 +47,3 @@ func TestAgentConfig(t *testing.T) { assert.Equal(t, time.Second*123, cfg.AgentConfig.Cache.Expiration) }) } - -func TestAgentConfigs(t *testing.T) { - cfg, err := NewConfig(config.MustNewConfigFrom(`{"agent_config":[{"service.environment":"production","config":{"transaction_sample_rate":0.5}}]}`), nil) - require.NoError(t, err) - assert.NotNil(t, cfg) - assert.Len(t, cfg.FleetAgentConfigs, 1) - assert.NotEmpty(t, cfg.FleetAgentConfigs[0].Etag) - - // The "config" attribute may come through as `null` when no config attributes are defined. - cfg, err = NewConfig(config.MustNewConfigFrom(`{"agent_config":[{"service.environment":"production","config":null}]}`), nil) - require.NoError(t, err) - assert.NotNil(t, cfg) - assert.Len(t, cfg.FleetAgentConfigs, 1) - assert.NotEmpty(t, cfg.FleetAgentConfigs[0].Etag) -} diff --git a/internal/beater/config/config.go b/internal/beater/config/config.go index 55782c6f3c7..23c411450c5 100644 --- a/internal/beater/config/config.go +++ b/internal/beater/config/config.go @@ -65,8 +65,6 @@ type Config struct { DefaultServiceEnvironment string `config:"default_service_environment"` JavaAttacherConfig JavaAttacherConfig `config:"java_attacher"` - FleetAgentConfigs []FleetAgentConfig `config:"agent_config"` - // WaitReadyInterval holds the interval for checks when waiting for // the integration package to be installed, and for checking the // Elasticsearch license level. @@ -89,12 +87,6 @@ func NewConfig(ucfg *config.C, outputESCfg *config.C) (*Config, error) { return nil, errors.Wrap(err, "Error processing configuration") } - for i := range c.FleetAgentConfigs { - if err := c.FleetAgentConfigs[i].setup(); err != nil { - return nil, err - } - } - if err := c.AgentConfig.setup(logger, outputESCfg); err != nil { return nil, err } diff --git a/internal/beater/config/config_test.go b/internal/beater/config/config_test.go index 9b136f95b72..fbc8c08d3d3 100644 --- a/internal/beater/config/config_test.go +++ b/internal/beater/config/config_test.go @@ -362,7 +362,6 @@ func TestUnpackConfig(t *testing.T) { ESConfig: elasticsearch.DefaultConfig(), Interval: 1 * time.Minute, IngestRateDecayFactor: 0.25, - StorageGCInterval: 5 * time.Minute, StorageLimit: "3GB", StorageLimitParsed: 3000000000, TTL: 30 * time.Minute, @@ -494,7 +493,6 @@ func TestUnpackConfig(t *testing.T) { ESConfig: elasticsearch.DefaultConfig(), Interval: 2 * time.Minute, IngestRateDecayFactor: 1.0, - StorageGCInterval: 5 * time.Minute, StorageLimit: "1GB", StorageLimitParsed: 1000000000, TTL: 30 * time.Minute, diff --git a/internal/beater/config/sampling.go b/internal/beater/config/sampling.go index df4e84d9dc0..07bff0d1a23 100644 --- a/internal/beater/config/sampling.go +++ b/internal/beater/config/sampling.go @@ -48,10 +48,10 @@ type TailSamplingConfig struct { ESConfig *elasticsearch.Config `config:"elasticsearch"` Interval time.Duration `config:"interval" validate:"min=1s"` IngestRateDecayFactor float64 `config:"ingest_rate_decay" validate:"min=0, max=1"` - StorageGCInterval time.Duration `config:"storage_gc_interval" validate:"min=1s"` TTL time.Duration `config:"ttl" validate:"min=1s"` StorageLimit string `config:"storage_limit"` StorageLimitParsed uint64 + DiscardOnWriteFailure bool `config:"discard_on_write_failure"` esConfigured bool } @@ -150,9 +150,9 @@ func defaultTailSamplingConfig() TailSamplingConfig { ESConfig: elasticsearch.DefaultConfig(), Interval: 1 * time.Minute, IngestRateDecayFactor: 0.25, - StorageGCInterval: 5 * time.Minute, TTL: 30 * time.Minute, StorageLimit: "3GB", + DiscardOnWriteFailure: false, } parsed, err := humanize.ParseBytes(cfg.StorageLimit) if err != nil { diff --git a/internal/beater/http.go b/internal/beater/http.go index 3c9993658a5..33e1ffbfac8 100644 --- a/internal/beater/http.go +++ b/internal/beater/http.go @@ -106,9 +106,9 @@ func (h *httpServer) start() error { return h.Serve(h.httpListener) } -func (h *httpServer) stop() { +func (h *httpServer) stop(ctx context.Context) { h.logger.Infof("Stop listening on: %s", h.Server.Addr) - if err := h.Shutdown(context.Background()); err != nil { + if err := h.Shutdown(ctx); err != nil { h.logger.Errorf("error stopping http server: %s", err.Error()) if err := h.Close(); err != nil { h.logger.Errorf("error closing http server: %s", err.Error()) diff --git a/internal/beater/interceptors/metrics.go b/internal/beater/interceptors/metrics.go index 8addfdddc15..b12c2a0eb6c 100644 --- a/internal/beater/interceptors/metrics.go +++ b/internal/beater/interceptors/metrics.go @@ -21,7 +21,6 @@ import ( "context" "time" - "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/metric" "google.golang.org/grpc" "google.golang.org/grpc/codes" @@ -29,31 +28,12 @@ import ( "github.com/elastic/apm-server/internal/beater/request" "github.com/elastic/elastic-agent-libs/logp" - "github.com/elastic/elastic-agent-libs/monitoring" ) const ( requestDurationHistogram = "request.duration" ) -var methodUnaryRequestMetrics = make(map[string]map[request.ResultID]*monitoring.Int) - -// RegisterMethodUnaryRequestMetrics registers a UnaryRequestMetrics for the -// given full method name. This can be used when the gRPC service implementation -// is not exensible, such as in the case of the OTLP services. -// -// This function must only be called from package init functions; it is not safe -// for concurrent access. -func RegisterMethodUnaryRequestMetrics(fullMethod string, m map[request.ResultID]*monitoring.Int) { - methodUnaryRequestMetrics[fullMethod] = m -} - -// UnaryRequestMetrics is an interface that gRPC services may implement -// to provide a metrics registry for the Metrics interceptor. -type UnaryRequestMetrics interface { - RequestMetrics(fullMethod string) map[request.ResultID]*monitoring.Int -} - type metricsInterceptor struct { logger *logp.Logger meter metric.Meter @@ -69,24 +49,24 @@ func (m *metricsInterceptor) Interceptor() grpc.UnaryServerInterceptor { info *grpc.UnaryServerInfo, handler grpc.UnaryHandler, ) (interface{}, error) { - var ints map[request.ResultID]*monitoring.Int - if requestMetrics, ok := info.Server.(UnaryRequestMetrics); ok { - ints = requestMetrics.RequestMetrics(info.FullMethod) - } else { - ints = methodUnaryRequestMetrics[info.FullMethod] - } - if ints == nil { + var legacyMetricsPrefix string + + switch info.FullMethod { + case "/opentelemetry.proto.collector.metrics.v1.MetricsService/Export": + legacyMetricsPrefix = "apm-server.otlp.grpc.metrics." + case "/opentelemetry.proto.collector.trace.v1.TraceService/Export": + legacyMetricsPrefix = "apm-server.otlp.grpc.traces." + case "/opentelemetry.proto.collector.logs.v1.LogsService/Export": + legacyMetricsPrefix = "apm-server.otlp.grpc.logs." + default: m.logger.With( "grpc.request.method", info.FullMethod, ).Warn("metrics registry missing") return handler(ctx, req) } - m.getCounter(string(request.IDRequestCount)).Add(ctx, 1) - defer m.getCounter(string(request.IDResponseCount)).Add(ctx, 1) - - ints[request.IDRequestCount].Inc() - defer ints[request.IDResponseCount].Inc() + m.inc(ctx, legacyMetricsPrefix, request.IDRequestCount) + defer m.inc(ctx, legacyMetricsPrefix, request.IDResponseCount) start := time.Now() resp, err := handler(ctx, req) @@ -99,31 +79,29 @@ func (m *metricsInterceptor) Interceptor() grpc.UnaryServerInterceptor { if s, ok := status.FromError(err); ok { switch s.Code() { case codes.Unauthenticated: - m.getCounter(string(request.IDResponseErrorsUnauthorized)).Add(ctx, 1) - ints[request.IDResponseErrorsUnauthorized].Inc() + m.inc(ctx, legacyMetricsPrefix, request.IDResponseErrorsUnauthorized) case codes.DeadlineExceeded, codes.Canceled: - m.getCounter(string(request.IDResponseErrorsTimeout)).Add(ctx, 1) - ints[request.IDResponseErrorsTimeout].Inc() + m.inc(ctx, legacyMetricsPrefix, request.IDResponseErrorsTimeout) case codes.ResourceExhausted: - m.getCounter(string(request.IDResponseErrorsRateLimit)).Add(ctx, 1) - ints[request.IDResponseErrorsRateLimit].Inc() + m.inc(ctx, legacyMetricsPrefix, request.IDResponseErrorsRateLimit) } } } - - m.getCounter(string(responseID)).Add(ctx, 1) - ints[responseID].Inc() - + m.inc(ctx, legacyMetricsPrefix, responseID) return resp, err } } -func (m *metricsInterceptor) getCounter(n string) metric.Int64Counter { - name := "grpc.server." + n +func (m *metricsInterceptor) inc(ctx context.Context, legacyMetricsPrefix string, id request.ResultID) { + m.getCounter("grpc.server.", string(id)).Add(ctx, 1) + m.getCounter(legacyMetricsPrefix, string(id)).Add(ctx, 1) +} + +func (m *metricsInterceptor) getCounter(prefix, n string) metric.Int64Counter { + name := prefix + n if met, ok := m.counters[name]; ok { return met } - nm, _ := m.meter.Int64Counter(name) m.counters[name] = nm return nm @@ -151,13 +129,9 @@ func (m *metricsInterceptor) getHistogram(n string, opts ...metric.Int64Histogra // if neither of these are available, a warning will be logged and no metrics // will be gathered. func Metrics(logger *logp.Logger, mp metric.MeterProvider) grpc.UnaryServerInterceptor { - if mp == nil { - mp = otel.GetMeterProvider() - } - i := &metricsInterceptor{ logger: logger, - meter: mp.Meter("internal/beater/interceptors"), + meter: mp.Meter("github.com/elastic/apm-server/internal/beater/interceptors"), counters: map[string]metric.Int64Counter{}, histograms: map[string]metric.Int64Histogram{}, diff --git a/internal/beater/interceptors/metrics_test.go b/internal/beater/interceptors/metrics_test.go index 211d14fd7b0..bec190a50b2 100644 --- a/internal/beater/interceptors/metrics_test.go +++ b/internal/beater/interceptors/metrics_test.go @@ -22,7 +22,6 @@ import ( "errors" "testing" - "github.com/stretchr/testify/assert" sdkmetric "go.opentelemetry.io/otel/sdk/metric" "go.opentelemetry.io/otel/sdk/metric/metricdata" "google.golang.org/grpc" @@ -32,210 +31,148 @@ import ( "github.com/elastic/apm-server/internal/beater/monitoringtest" "github.com/elastic/apm-server/internal/beater/request" "github.com/elastic/elastic-agent-libs/logp" - "github.com/elastic/elastic-agent-libs/monitoring" -) - -var monitoringKeys = append( - request.DefaultResultIDs, - request.IDResponseErrorsRateLimit, - request.IDResponseErrorsTimeout, - request.IDResponseErrorsUnauthorized, ) func TestMetrics(t *testing.T) { - reader := sdkmetric.NewManualReader(sdkmetric.WithTemporalitySelector( - func(ik sdkmetric.InstrumentKind) metricdata.Temporality { - return metricdata.DeltaTemporality - }, - )) - mp := sdkmetric.NewMeterProvider(sdkmetric.WithReader(reader)) - - registry := monitoring.NewRegistry() - - monitoringMap := request.MonitoringMapForRegistry(registry, monitoringKeys) - methodName := "test_method_name" - logger := logp.NewLogger("interceptor.metrics.test") - - interceptor := Metrics(logger, mp) - - ctx := context.Background() - info := &grpc.UnaryServerInfo{ - FullMethod: methodName, - Server: requestMetricsFunc(func(fullMethod string) map[request.ResultID]*monitoring.Int { - assert.Equal(t, methodName, fullMethod) - return monitoringMap - }), - } - - for _, tc := range []struct { - name string - f func(ctx context.Context, req interface{}) (interface{}, error) - monitoringInt map[request.ResultID]int64 - expectedOtel map[string]interface{} + for _, metrics := range []struct { + methodName string + prefix string }{ { - name: "with an error", - f: func(ctx context.Context, req interface{}) (interface{}, error) { - return nil, errors.New("error") - }, - monitoringInt: map[request.ResultID]int64{ - request.IDRequestCount: 1, - request.IDResponseCount: 1, - request.IDResponseValidCount: 0, - request.IDResponseErrorsCount: 1, - request.IDResponseErrorsRateLimit: 0, - request.IDResponseErrorsTimeout: 0, - request.IDResponseErrorsUnauthorized: 0, - }, - expectedOtel: map[string]interface{}{ - "grpc.server." + string(request.IDRequestCount): 1, - "grpc.server." + string(request.IDResponseCount): 1, - "grpc.server." + string(request.IDResponseErrorsCount): 1, - - "grpc.server.request.duration": 1, - }, + methodName: "/opentelemetry.proto.collector.metrics.v1.MetricsService/Export", + prefix: "apm-server.otlp.grpc.metrics.", }, { - name: "with an unauthenticated error", - f: func(ctx context.Context, req interface{}) (interface{}, error) { - return nil, status.Error(codes.Unauthenticated, "error") - }, - monitoringInt: map[request.ResultID]int64{ - request.IDRequestCount: 1, - request.IDResponseCount: 1, - request.IDResponseValidCount: 0, - request.IDResponseErrorsCount: 1, - request.IDResponseErrorsInternal: 0, - request.IDResponseErrorsRateLimit: 0, - request.IDResponseErrorsTimeout: 0, - request.IDResponseErrorsUnauthorized: 1, - }, - expectedOtel: map[string]interface{}{ - "grpc.server." + string(request.IDRequestCount): 1, - "grpc.server." + string(request.IDResponseCount): 1, - "grpc.server." + string(request.IDResponseErrorsCount): 1, - "grpc.server." + string(request.IDResponseErrorsUnauthorized): 1, - - "grpc.server.request.duration": 1, - }, + methodName: "/opentelemetry.proto.collector.trace.v1.TraceService/Export", + prefix: "apm-server.otlp.grpc.traces.", }, { - name: "with a deadline exceeded error", - f: func(ctx context.Context, req interface{}) (interface{}, error) { - return nil, status.Error(codes.DeadlineExceeded, "request timed out") - }, - monitoringInt: map[request.ResultID]int64{ - request.IDRequestCount: 1, - request.IDResponseCount: 1, - request.IDResponseValidCount: 0, - request.IDResponseErrorsCount: 1, - request.IDResponseErrorsInternal: 0, - request.IDResponseErrorsRateLimit: 0, - request.IDResponseErrorsTimeout: 1, - request.IDResponseErrorsUnauthorized: 0, - }, - expectedOtel: map[string]interface{}{ - "grpc.server." + string(request.IDRequestCount): 1, - "grpc.server." + string(request.IDResponseCount): 1, - "grpc.server." + string(request.IDResponseErrorsCount): 1, - "grpc.server." + string(request.IDResponseErrorsTimeout): 1, - - "grpc.server.request.duration": 1, - }, + methodName: "/opentelemetry.proto.collector.logs.v1.LogsService/Export", + prefix: "apm-server.otlp.grpc.logs.", }, - { - name: "with a canceled error", - f: func(ctx context.Context, req interface{}) (interface{}, error) { - return nil, status.Error(codes.Canceled, "request timed out") - }, - monitoringInt: map[request.ResultID]int64{ - request.IDRequestCount: 1, - request.IDResponseCount: 1, - request.IDResponseValidCount: 0, - request.IDResponseErrorsCount: 1, - request.IDResponseErrorsInternal: 0, - request.IDResponseErrorsRateLimit: 0, - request.IDResponseErrorsTimeout: 1, - request.IDResponseErrorsUnauthorized: 0, + } { + reader := sdkmetric.NewManualReader(sdkmetric.WithTemporalitySelector( + func(ik sdkmetric.InstrumentKind) metricdata.Temporality { + return metricdata.DeltaTemporality }, - expectedOtel: map[string]interface{}{ - "grpc.server." + string(request.IDRequestCount): 1, - "grpc.server." + string(request.IDResponseCount): 1, - "grpc.server." + string(request.IDResponseErrorsCount): 1, - "grpc.server." + string(request.IDResponseErrorsTimeout): 1, + )) + mp := sdkmetric.NewMeterProvider(sdkmetric.WithReader(reader)) - "grpc.server.request.duration": 1, - }, - }, - { - name: "with a resource exhausted error", - f: func(ctx context.Context, req interface{}) (interface{}, error) { - return nil, status.Error(codes.ResourceExhausted, "rate limit exceeded") - }, - monitoringInt: map[request.ResultID]int64{ - request.IDRequestCount: 1, - request.IDResponseCount: 1, - request.IDResponseValidCount: 0, - request.IDResponseErrorsCount: 1, - request.IDResponseErrorsInternal: 0, - request.IDResponseErrorsRateLimit: 1, - request.IDResponseErrorsTimeout: 0, - request.IDResponseErrorsUnauthorized: 0, - }, - expectedOtel: map[string]interface{}{ - "grpc.server." + string(request.IDRequestCount): 1, - "grpc.server." + string(request.IDResponseCount): 1, - "grpc.server." + string(request.IDResponseErrorsCount): 1, - "grpc.server." + string(request.IDResponseErrorsRateLimit): 1, + logger := logp.NewLogger("interceptor.metrics.test") - "grpc.server.request.duration": 1, - }, - }, - { - name: "with a success", - f: func(ctx context.Context, req interface{}) (interface{}, error) { - return nil, nil - }, - monitoringInt: map[request.ResultID]int64{ - request.IDRequestCount: 1, - request.IDResponseCount: 1, - request.IDResponseValidCount: 1, - request.IDResponseErrorsCount: 0, - request.IDResponseErrorsInternal: 0, - request.IDResponseErrorsRateLimit: 0, - request.IDResponseErrorsTimeout: 0, - request.IDResponseErrorsUnauthorized: 0, - }, - expectedOtel: map[string]interface{}{ - "grpc.server." + string(request.IDRequestCount): 1, - "grpc.server." + string(request.IDResponseCount): 1, - "grpc.server." + string(request.IDResponseValidCount): 1, + interceptor := Metrics(logger, mp) - "grpc.server.request.duration": 1, - }, - }, - } { - t.Run(tc.name, func(t *testing.T) { - interceptor(ctx, nil, info, tc.f) - assertMonitoring(t, tc.monitoringInt, monitoringMap) - monitoringtest.ClearRegistry(monitoringMap) - monitoringtest.ExpectOtelMetrics(t, reader, tc.expectedOtel) - }) - } -} + ctx := context.Background() + info := &grpc.UnaryServerInfo{ + FullMethod: metrics.methodName, + } -func assertMonitoring(t *testing.T, expected map[request.ResultID]int64, actual map[request.ResultID]*monitoring.Int) { - for _, k := range monitoringKeys { - if val, ok := expected[k]; ok { - assert.Equalf(t, val, actual[k].Get(), "%s mismatch", k) - } else { - assert.Zerof(t, actual[k].Get(), "%s mismatch", k) + for _, tc := range []struct { + name string + f func(ctx context.Context, req interface{}) (interface{}, error) + monitoringInt map[request.ResultID]int64 + expectedOtel map[string]interface{} + }{ + { + name: "with an error", + f: func(ctx context.Context, req interface{}) (interface{}, error) { + return nil, errors.New("error") + }, + expectedOtel: map[string]interface{}{ + string(request.IDRequestCount): 1, + string(request.IDResponseCount): 1, + string(request.IDResponseErrorsCount): 1, + + "request.duration": 1, + }, + }, + { + name: "with an unauthenticated error", + f: func(ctx context.Context, req interface{}) (interface{}, error) { + return nil, status.Error(codes.Unauthenticated, "error") + }, + expectedOtel: map[string]interface{}{ + string(request.IDRequestCount): 1, + string(request.IDResponseCount): 1, + string(request.IDResponseErrorsCount): 1, + string(request.IDResponseErrorsUnauthorized): 1, + + "request.duration": 1, + }, + }, + { + name: "with a deadline exceeded error", + f: func(ctx context.Context, req interface{}) (interface{}, error) { + return nil, status.Error(codes.DeadlineExceeded, "request timed out") + }, + expectedOtel: map[string]interface{}{ + string(request.IDRequestCount): 1, + string(request.IDResponseCount): 1, + string(request.IDResponseErrorsCount): 1, + string(request.IDResponseErrorsTimeout): 1, + + "request.duration": 1, + }, + }, + { + name: "with a canceled error", + f: func(ctx context.Context, req interface{}) (interface{}, error) { + return nil, status.Error(codes.Canceled, "request timed out") + }, + expectedOtel: map[string]interface{}{ + string(request.IDRequestCount): 1, + string(request.IDResponseCount): 1, + string(request.IDResponseErrorsCount): 1, + string(request.IDResponseErrorsTimeout): 1, + + "request.duration": 1, + }, + }, + { + name: "with a resource exhausted error", + f: func(ctx context.Context, req interface{}) (interface{}, error) { + return nil, status.Error(codes.ResourceExhausted, "rate limit exceeded") + }, + expectedOtel: map[string]interface{}{ + string(request.IDRequestCount): 1, + string(request.IDResponseCount): 1, + string(request.IDResponseErrorsCount): 1, + string(request.IDResponseErrorsRateLimit): 1, + + "request.duration": 1, + }, + }, + { + name: "with a success", + f: func(ctx context.Context, req interface{}) (interface{}, error) { + return nil, nil + }, + expectedOtel: map[string]interface{}{ + string(request.IDRequestCount): 1, + string(request.IDResponseCount): 1, + string(request.IDResponseValidCount): 1, + + "request.duration": 1, + }, + }, + } { + t.Run(tc.name, func(t *testing.T) { + interceptor(ctx, nil, info, tc.f) + + expectedMetrics := make(map[string]any, 2*len(tc.expectedOtel)) + + for k, v := range tc.expectedOtel { + // add otel metrics + expectedMetrics["grpc.server."+k] = v + + if k != "request.duration" { + // add legacy metrics + expectedMetrics[metrics.prefix+k] = v + } + } + + monitoringtest.ExpectOtelMetrics(t, reader, expectedMetrics) + }) } } } - -type requestMetricsFunc func(fullMethod string) map[request.ResultID]*monitoring.Int - -func (f requestMetricsFunc) RequestMetrics(fullMethod string) map[request.ResultID]*monitoring.Int { - return f(fullMethod) -} diff --git a/internal/beater/jaeger/grpc.go b/internal/beater/jaeger/grpc.go deleted file mode 100644 index f0c722d56e2..00000000000 --- a/internal/beater/jaeger/grpc.go +++ /dev/null @@ -1,276 +0,0 @@ -// Licensed to Elasticsearch B.V. under one or more contributor -// license agreements. See the NOTICE file distributed with -// this work for additional information regarding copyright -// ownership. Elasticsearch B.V. licenses this file to you under -// the Apache License, Version 2.0 (the "License"); you may -// not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -package jaeger - -import ( - "context" - "errors" - "fmt" - "strconv" - "sync" - - jaegermodel "github.com/jaegertracing/jaeger/model" - "github.com/jaegertracing/jaeger/proto-gen/api_v2" - jaegertranslator "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/translator/jaeger" - "go.opentelemetry.io/collector/consumer" - "go.uber.org/zap" - "google.golang.org/grpc" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" - - "github.com/elastic/elastic-agent-libs/monitoring" - - "github.com/elastic/apm-data/input" - "github.com/elastic/apm-data/input/otlp" - "github.com/elastic/apm-data/model/modelpb" - "github.com/elastic/apm-server/internal/agentcfg" - "github.com/elastic/apm-server/internal/beater/auth" - "github.com/elastic/apm-server/internal/beater/config" - "github.com/elastic/apm-server/internal/beater/request" -) - -var ( - gRPCCollectorRegistry = monitoring.Default.NewRegistry("apm-server.jaeger.grpc.collect") - gRPCCollectorMonitoringMap monitoringMap = request.MonitoringMapForRegistry( - gRPCCollectorRegistry, append(request.DefaultResultIDs, - request.IDResponseErrorsRateLimit, - request.IDResponseErrorsTimeout, - request.IDResponseErrorsUnauthorized, - ), - ) -) - -const ( - // elasticAuthTag is the name of the agent tag that will be used for auth. - // The tag value should be "Bearer ". - elasticAuthTag = "elastic-apm-auth" - - deprecationNotice = "deprecation notice: support for Jaeger will be removed in an upcoming version" -) - -// RegisterGRPCServices registers Jaeger gRPC services with srv. -func RegisterGRPCServices( - srv *grpc.Server, - logger *zap.Logger, - processor modelpb.BatchProcessor, - fetcher agentcfg.Fetcher, - semaphore input.Semaphore, -) { - traceConsumer := otlp.NewConsumer(otlp.ConsumerConfig{ - Processor: processor, - Logger: logger, - Semaphore: semaphore, - }) - - logger.Info(deprecationNotice) - - api_v2.RegisterCollectorServiceServer(srv, &grpcCollector{sync.Once{}, logger, traceConsumer}) - api_v2.RegisterSamplingManagerServer(srv, &grpcSampler{sync.Once{}, logger, fetcher}) -} - -// grpcCollector implements Jaeger api_v2 protocol for receiving tracing data -type grpcCollector struct { - // Use an atomic counter to ensure concurrent safety. - once sync.Once - logger *zap.Logger - consumer consumer.Traces -} - -// AuthenticateUnaryCall authenticates CollectorService calls. -func (c *grpcCollector) AuthenticateUnaryCall( - ctx context.Context, - req interface{}, - fullMethodName string, - authenticator *auth.Authenticator, -) (auth.AuthenticationDetails, auth.Authorizer, error) { - postSpansRequest, ok := req.(*api_v2.PostSpansRequest) - if !ok { - return auth.AuthenticationDetails{}, nil, status.Errorf( - codes.Unauthenticated, "unhandled method %q", fullMethodName, - ) - } - batch := &postSpansRequest.Batch - var kind, token string - for i, kv := range batch.Process.GetTags() { - if kv.Key != elasticAuthTag { - continue - } - // Remove the auth tag. - batch.Process.Tags = append(batch.Process.Tags[:i], batch.Process.Tags[i+1:]...) - kind, token = auth.ParseAuthorizationHeader(kv.VStr) - break - } - return authenticator.Authenticate(ctx, kind, token) -} - -// MonitoringMap returns the request metrics registry for this service, -// to support interceptors.Metrics. -func (c *grpcCollector) RequestMetrics(fullMethodName string) map[request.ResultID]*monitoring.Int { - return gRPCCollectorMonitoringMap -} - -// PostSpans implements the api_v2/collector.proto. It converts spans received via Jaeger Proto batch to open-telemetry -// TraceData and passes them on to the internal Consumer taking care of converting into Elastic APM format. -// The implementation of the protobuf contract is based on the open-telemetry implementation at -// https://github.com/open-telemetry/opentelemetry-collector/tree/master/receiver/jaegerreceiver -func (c *grpcCollector) PostSpans(ctx context.Context, r *api_v2.PostSpansRequest) (*api_v2.PostSpansResponse, error) { - - c.once.Do(func() { - c.logger.Warn(deprecationNotice) - }) - - if err := c.postSpans(ctx, r.Batch); err != nil { - return nil, err - } - return &api_v2.PostSpansResponse{}, nil -} - -func (c *grpcCollector) postSpans(ctx context.Context, batch jaegermodel.Batch) error { - spanCount := int64(len(batch.Spans)) - gRPCCollectorMonitoringMap.add(request.IDEventReceivedCount, spanCount) - traces, err := jaegertranslator.ProtoToTraces([]*jaegermodel.Batch{&batch}) - if err != nil { - return err - } - return c.consumer.ConsumeTraces(ctx, traces) -} - -var ( - gRPCSamplingRegistry = monitoring.Default.NewRegistry("apm-server.jaeger.grpc.sampling") - gRPCSamplingMonitoringMap monitoringMap = request.MonitoringMapForRegistry( - gRPCSamplingRegistry, append(request.DefaultResultIDs, request.IDEventReceivedCount), - ) - - jaegerAgentPrefixes = []string{otlp.AgentNameJaeger} -) - -type grpcSampler struct { - // Use an atomic counter to ensure concurrent safety. - once sync.Once - logger *zap.Logger - fetcher agentcfg.Fetcher -} - -// GetSamplingStrategy implements the api_v2/sampling.proto. -// Only probabilistic sampling is supported. -// It fetches the sampling rate from the central configuration management and returns the sampling strategy. -func (s *grpcSampler) GetSamplingStrategy( - ctx context.Context, - params *api_v2.SamplingStrategyParameters) (*api_v2.SamplingStrategyResponse, error) { - - s.once.Do(func() { - s.logger.Warn(deprecationNotice) - }) - - samplingRate, err := s.fetchSamplingRate(ctx, params.ServiceName) - if err != nil { - // do not return full error details since this is part of an unprotected endpoint response - s.logger.Error("no valid sampling rate fetched from Kibana", zap.Error(err)) - return nil, errors.New("no sampling rate available, check server logs for more details") - } - - return &api_v2.SamplingStrategyResponse{ - StrategyType: api_v2.SamplingStrategyType_PROBABILISTIC, - ProbabilisticSampling: &api_v2.ProbabilisticSamplingStrategy{SamplingRate: samplingRate}, - }, nil -} - -func (s *grpcSampler) fetchSamplingRate(ctx context.Context, service string) (float64, error) { - // Only service, and not agent, is known for config queries. - // For anonymous/untrusted agents, we filter the results using - // query.InsecureAgents below. - authResource := auth.Resource{ServiceName: service} - if err := auth.Authorize(ctx, auth.ActionAgentConfig, authResource); err != nil { - return 0, err - } - - query := agentcfg.Query{ - Service: agentcfg.Service{Name: service}, - InsecureAgents: jaegerAgentPrefixes, - MarkAsAppliedByAgent: true, - } - result, err := s.fetcher.Fetch(ctx, query) - if err != nil { - gRPCSamplingMonitoringMap.inc(request.IDResponseErrorsServiceUnavailable) - return 0, fmt.Errorf("fetching sampling rate failed: %w", err) - } - - if sr, ok := result.Source.Settings[agentcfg.TransactionSamplingRateKey]; ok { - srFloat64, err := strconv.ParseFloat(sr, 64) - if err != nil { - gRPCSamplingMonitoringMap.inc(request.IDResponseErrorsInternal) - return 0, fmt.Errorf("parsing error for sampling rate `%v`: %w", sr, err) - } - return srFloat64, nil - } - gRPCSamplingMonitoringMap.inc(request.IDResponseErrorsNotFound) - return 0, fmt.Errorf("no sampling rate found for %v", service) -} - -var anonymousAuthenticator *auth.Authenticator - -func init() { - // TODO(axw) introduce a function in the auth package for returning - // anonymous details/authorizer, obviating the need for a separate - // anonymous Authenticator. - var err error - anonymousAuthenticator, err = auth.NewAuthenticator(config.AgentAuth{ - Anonymous: config.AnonymousAgentAuth{Enabled: true}, - }) - if err != nil { - panic(err) - } -} - -// AuthenticateUnaryCall authenticates SamplingManager calls. -// -// Sampling strategy queries are always unauthenticated. We still consult -// the authenticator in case auth isn't required, in which case we should -// not rate limit the request. -func (s *grpcSampler) AuthenticateUnaryCall( - ctx context.Context, - req interface{}, - fullMethodName string, - authenticator *auth.Authenticator, -) (auth.AuthenticationDetails, auth.Authorizer, error) { - details, authz, err := authenticator.Authenticate(ctx, "", "") - if !errors.Is(err, auth.ErrAuthFailed) { - return details, authz, err - } - return anonymousAuthenticator.Authenticate(ctx, "", "") -} - -// MonitoringMap returns the request metrics registry for this service, -// to support interceptors.Metrics. -func (s *grpcSampler) RequestMetrics(fullMethodName string) map[request.ResultID]*monitoring.Int { - return gRPCSamplingMonitoringMap -} - -type monitoringMap map[request.ResultID]*monitoring.Int - -func (m monitoringMap) inc(id request.ResultID) { - if counter, ok := m[id]; ok { - counter.Inc() - } -} - -func (m monitoringMap) add(id request.ResultID, n int64) { - if counter, ok := m[id]; ok { - counter.Add(n) - } -} diff --git a/internal/beater/jaeger/grpc_test.go b/internal/beater/jaeger/grpc_test.go deleted file mode 100644 index 6b0914a4349..00000000000 --- a/internal/beater/jaeger/grpc_test.go +++ /dev/null @@ -1,257 +0,0 @@ -// Licensed to Elasticsearch B.V. under one or more contributor -// license agreements. See the NOTICE file distributed with -// this work for additional information regarding copyright -// ownership. Elasticsearch B.V. licenses this file to you under -// the Apache License, Version 2.0 (the "License"); you may -// not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -package jaeger - -import ( - "context" - "errors" - "net" - "testing" - - "github.com/jaegertracing/jaeger/proto-gen/api_v2" - jaegertranslator "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/translator/jaeger" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - "go.opentelemetry.io/collector/pdata/pcommon" - "go.opentelemetry.io/collector/pdata/ptrace" - "go.uber.org/zap" - "go.uber.org/zap/zaptest/observer" - "golang.org/x/sync/semaphore" - "google.golang.org/grpc" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/credentials/insecure" - "google.golang.org/grpc/status" - - "github.com/elastic/elastic-agent-libs/logp" - - "github.com/elastic/apm-data/model/modelpb" - "github.com/elastic/apm-server/internal/agentcfg" - "github.com/elastic/apm-server/internal/beater/auth" - "github.com/elastic/apm-server/internal/beater/config" - "github.com/elastic/apm-server/internal/beater/interceptors" -) - -func TestPostSpans(t *testing.T) { - var processorErr error - var processor modelpb.ProcessBatchFunc = func(ctx context.Context, batch *modelpb.Batch) error { - return processorErr - } - conn, logs := newServer(t, processor, nil) - - client := api_v2.NewCollectorServiceClient(conn) - result, err := client.PostSpans(context.Background(), &api_v2.PostSpansRequest{}) - assert.NoError(t, err) - assert.NotNil(t, result) - - type testcase struct { - request *api_v2.PostSpansRequest - processorErr error - expectedErr error - } - - for name, tc := range map[string]testcase{ - "empty request": { - request: &api_v2.PostSpansRequest{}, - }, - "successful request": { - request: newPostSpansRequest(t), - }, - "failing request": { - request: newPostSpansRequest(t), - processorErr: errors.New("processor failed"), - expectedErr: status.Error(codes.Unknown, "processor failed"), - }, - } { - t.Run(name, func(t *testing.T) { - processorErr = tc.processorErr - resp, err := client.PostSpans(context.Background(), tc.request) - - // Deprecation log shown on server startup. - log := logs.All()[0] - assert.Equal(t, log.Level, zap.InfoLevel) - assert.Contains(t, log.Message, deprecationNotice) - - // Deprecation log shown on first endpoint hit. - log = logs.All()[1] - assert.Equal(t, log.Level, zap.WarnLevel) - assert.Contains(t, log.Message, deprecationNotice) - - if tc.expectedErr != nil { - assert.Nil(t, resp) - assert.Error(t, err) - assert.Equal(t, tc.expectedErr, err) - } else { - assert.NotNil(t, resp) - assert.NoError(t, err) - } - }) - } -} - -func newPostSpansRequest(t *testing.T) *api_v2.PostSpansRequest { - traces := ptrace.NewTraces() - resourceSpans := traces.ResourceSpans().AppendEmpty() - spans := resourceSpans.ScopeSpans().AppendEmpty() - span0 := spans.Spans().AppendEmpty() - span0.SetTraceID(pcommon.TraceID{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}) - span0.SetSpanID(pcommon.SpanID{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}) - span1 := spans.Spans().AppendEmpty() - span1.SetTraceID(pcommon.TraceID{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}) - span1.SetSpanID(pcommon.SpanID{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}) - - batches, err := jaegertranslator.ProtoFromTraces(traces) - require.NoError(t, err) - require.Len(t, batches, 1) - return &api_v2.PostSpansRequest{Batch: *batches[0]} -} - -func TestGRPCSampler_GetSamplingStrategy(t *testing.T) { - type testcase struct { - params *api_v2.SamplingStrategyParameters - fetcher agentcfg.Fetcher - expectedSamplingRate float64 - expectedErrMsg string - expectedLogMsg string - expectedLogError string - } - - for name, tc := range map[string]testcase{ - "unauthorized": { - params: &api_v2.SamplingStrategyParameters{ServiceName: unauthorizedServiceName}, - expectedErrMsg: "no sampling rate available", - expectedLogMsg: "no valid sampling rate fetched", - expectedLogError: `unauthorized: anonymous access not permitted for service "serviceB"`, - }, - "withSamplingRate": { - params: &api_v2.SamplingStrategyParameters{ServiceName: authorizedServiceName}, - fetcher: mockAgentConfigFetcher(agentcfg.Result{ - Source: agentcfg.Source{ - Settings: agentcfg.Settings{ - agentcfg.TransactionSamplingRateKey: "0.75", - }, - }, - }, nil), - expectedSamplingRate: 0.75, - }, - "noSamplingRate": { - params: &api_v2.SamplingStrategyParameters{ServiceName: authorizedServiceName}, - fetcher: mockAgentConfigFetcher(agentcfg.Result{ - Source: agentcfg.Source{ - Settings: agentcfg.Settings{}, - }, - }, nil), - expectedErrMsg: "no sampling rate available", - expectedLogMsg: "no valid sampling rate fetched", - }, - "invalidSamplingRate": { - params: &api_v2.SamplingStrategyParameters{ServiceName: authorizedServiceName}, - fetcher: mockAgentConfigFetcher(agentcfg.Result{ - Source: agentcfg.Source{ - Settings: agentcfg.Settings{ - agentcfg.TransactionSamplingRateKey: "foo", - }, - }, - }, nil), - expectedErrMsg: "no sampling rate available", - expectedLogMsg: "no valid sampling rate fetched", - }, - } { - t.Run(name, func(t *testing.T) { - require.NoError(t, logp.DevelopmentSetup(logp.ToObserverOutput())) - - conn, logs := newServer(t, nil, tc.fetcher) - client := api_v2.NewSamplingManagerClient(conn) - resp, err := client.GetSamplingStrategy(context.Background(), tc.params) - - // Deprecation log shown on server startup. - log := logs.All()[0] - assert.Equal(t, log.Level, zap.InfoLevel) - assert.Contains(t, log.Message, deprecationNotice) - - // Deprecation log shown on first endpoint hit. - log = logs.All()[1] - assert.Equal(t, log.Level, zap.WarnLevel) - assert.Contains(t, log.Message, deprecationNotice) - - // assert sampling response - if tc.expectedErrMsg != "" { - require.Error(t, err) - assert.Contains(t, err.Error(), tc.expectedErrMsg) - assert.Nil(t, resp) - - require.Equal(t, 3, logs.Len()) - - log = logs.All()[2] - assert.Contains(t, log.Message, tc.expectedLogMsg) - - if tc.expectedLogError != "" { - assert.Equal(t, tc.expectedLogError, log.ContextMap()["error"]) - } - } else { - require.NoError(t, err) - require.Equal(t, api_v2.SamplingStrategyType_PROBABILISTIC, resp.StrategyType) - assert.Equal(t, tc.expectedSamplingRate, resp.ProbabilisticSampling.SamplingRate) - assert.Nil(t, resp.OperationSampling) - assert.Nil(t, resp.RateLimitingSampling) - } - }) - } -} - -const ( - authorizedServiceName = "serviceA" - unauthorizedServiceName = "serviceB" -) - -func newServer(t *testing.T, batchProcessor modelpb.BatchProcessor, agentcfgFetcher agentcfg.Fetcher) (*grpc.ClientConn, *observer.ObservedLogs) { - lis, err := net.Listen("tcp", "localhost:0") - require.NoError(t, err) - - authenticator, err := auth.NewAuthenticator(config.AgentAuth{ - Anonymous: config.AnonymousAgentAuth{ - Enabled: true, - AllowService: []string{authorizedServiceName}, - }, - SecretToken: "abc123", - }) - require.NoError(t, err) - srv := grpc.NewServer(grpc.UnaryInterceptor(interceptors.Auth(authenticator))) - semaphore := semaphore.NewWeighted(1) - - core, observedLogs := observer.New(zap.DebugLevel) - RegisterGRPCServices(srv, zap.New(core), batchProcessor, agentcfgFetcher, semaphore) - - go srv.Serve(lis) - t.Cleanup(srv.GracefulStop) - conn, err := grpc.NewClient(lis.Addr().String(), grpc.WithTransportCredentials(insecure.NewCredentials())) - require.NoError(t, err) - t.Cleanup(func() { conn.Close() }) - return conn, observedLogs -} - -func mockAgentConfigFetcher(result agentcfg.Result, err error) agentcfg.Fetcher { - return fetchAgentConfigFunc(func(ctx context.Context, query agentcfg.Query) (agentcfg.Result, error) { - return result, err - }) -} - -type fetchAgentConfigFunc func(context.Context, agentcfg.Query) (agentcfg.Result, error) - -func (f fetchAgentConfigFunc) Fetch(ctx context.Context, query agentcfg.Query) (agentcfg.Result, error) { - return f(ctx, query) -} diff --git a/internal/beater/middleware/log_middleware.go b/internal/beater/middleware/log_middleware.go index b16cb7092c3..1198fa83271 100644 --- a/internal/beater/middleware/log_middleware.go +++ b/internal/beater/middleware/log_middleware.go @@ -20,7 +20,7 @@ package middleware import ( "time" - "github.com/gofrs/uuid" + "github.com/gofrs/uuid/v5" "go.elastic.co/apm/v2" diff --git a/internal/beater/middleware/monitoring_middleware.go b/internal/beater/middleware/monitoring_middleware.go index 67c0125c285..9dd06eec4d4 100644 --- a/internal/beater/middleware/monitoring_middleware.go +++ b/internal/beater/middleware/monitoring_middleware.go @@ -20,13 +20,12 @@ package middleware import ( "context" "net/http" + "sync" "time" - "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/metric" "github.com/elastic/apm-server/internal/beater/request" - "github.com/elastic/elastic-agent-libs/monitoring" ) const ( @@ -34,11 +33,11 @@ const ( ) type monitoringMiddleware struct { - meter metric.Meter + meter metric.Meter + legacyMetricsPrefix string - ints map[request.ResultID]*monitoring.Int - counters map[string]metric.Int64Counter - histograms map[string]metric.Int64Histogram + counters sync.Map + histograms sync.Map } func (m *monitoringMiddleware) Middleware() Middleware { @@ -46,71 +45,59 @@ func (m *monitoringMiddleware) Middleware() Middleware { return func(c *request.Context) { ctx := context.Background() - m.getCounter(string(request.IDRequestCount)).Add(ctx, 1) - m.inc(request.IDRequestCount) + m.inc(ctx, request.IDRequestCount) start := time.Now() h(c) duration := time.Since(start) m.getHistogram(requestDurationHistogram, metric.WithUnit("ms")).Record(ctx, duration.Milliseconds()) - m.getCounter(string(request.IDResponseCount)).Add(ctx, 1) - m.inc(request.IDResponseCount) + m.inc(ctx, request.IDResponseCount) if c.Result.StatusCode >= http.StatusBadRequest { - m.getCounter(string(request.IDResponseErrorsCount)).Add(ctx, 1) - m.inc(request.IDResponseErrorsCount) + m.inc(ctx, request.IDResponseErrorsCount) } else { - m.getCounter(string(request.IDResponseValidCount)).Add(ctx, 1) - m.inc(request.IDResponseValidCount) + m.inc(ctx, request.IDResponseValidCount) } - - m.getCounter(string(c.Result.ID)).Add(ctx, 1) - m.inc(c.Result.ID) + m.inc(ctx, c.Result.ID) }, nil } } -func (m *monitoringMiddleware) inc(id request.ResultID) { - if counter, ok := m.ints[id]; ok { - counter.Inc() - } +func (m *monitoringMiddleware) inc(ctx context.Context, id request.ResultID) { + m.getCounter("http.server.", string(id)).Add(ctx, 1) + m.getCounter(m.legacyMetricsPrefix, string(id)).Add(ctx, 1) } -func (m *monitoringMiddleware) getCounter(n string) metric.Int64Counter { - name := "http.server." + n - if met, ok := m.counters[name]; ok { - return met +func (m *monitoringMiddleware) getCounter(prefix, name string) metric.Int64Counter { + name = prefix + name + if met, ok := m.counters.Load(name); ok { + return met.(metric.Int64Counter) } - nm, _ := m.meter.Int64Counter(name) - m.counters[name] = nm + m.counters.LoadOrStore(name, nm) return nm } func (m *monitoringMiddleware) getHistogram(n string, opts ...metric.Int64HistogramOption) metric.Int64Histogram { name := "http.server." + n - if met, ok := m.histograms[name]; ok { - return met + if met, ok := m.histograms.Load(name); ok { + return met.(metric.Int64Histogram) } nm, _ := m.meter.Int64Histogram(name, opts...) - m.histograms[name] = nm + m.histograms.LoadOrStore(name, nm) return nm } // MonitoringMiddleware returns a middleware that increases monitoring counters for collecting metrics // about request processing. As input parameter it takes a map capable of mapping a request.ResultID to a counter. -func MonitoringMiddleware(m map[request.ResultID]*monitoring.Int, mp metric.MeterProvider) Middleware { - if mp == nil { - mp = otel.GetMeterProvider() - } - +func MonitoringMiddleware(legacyMetricsPrefix string, mp metric.MeterProvider) Middleware { mid := &monitoringMiddleware{ - meter: mp.Meter("internal/beater/middleware"), - ints: m, - counters: map[string]metric.Int64Counter{}, - histograms: map[string]metric.Int64Histogram{}, + meter: mp.Meter("github.com/elastic/apm-server/internal/beater/middleware"), + legacyMetricsPrefix: legacyMetricsPrefix, + counters: sync.Map{}, + histograms: sync.Map{}, } return mid.Middleware() diff --git a/internal/beater/middleware/monitoring_middleware_test.go b/internal/beater/middleware/monitoring_middleware_test.go index cf78495bfd1..9c410e9eb5b 100644 --- a/internal/beater/middleware/monitoring_middleware_test.go +++ b/internal/beater/middleware/monitoring_middleware_test.go @@ -18,30 +18,20 @@ package middleware import ( + "sync" "testing" - "github.com/stretchr/testify/assert" sdkmetric "go.opentelemetry.io/otel/sdk/metric" "go.opentelemetry.io/otel/sdk/metric/metricdata" - "github.com/elastic/elastic-agent-libs/monitoring" - "github.com/elastic/apm-server/internal/beater/monitoringtest" "github.com/elastic/apm-server/internal/beater/request" ) -var ( - mockMonitoringRegistry = monitoring.Default.NewRegistry("mock.monitoring") - mockMonitoringNil = map[request.ResultID]*monitoring.Int{} - mockMonitoring = request.DefaultMonitoringMapForRegistry(mockMonitoringRegistry) -) - func TestMonitoringHandler(t *testing.T) { checkMonitoring := func(t *testing.T, h func(*request.Context), - expected map[request.ResultID]int, expectedOtel map[string]interface{}, - m map[request.ResultID]*monitoring.Int, ) { reader := sdkmetric.NewManualReader(sdkmetric.WithTemporalitySelector( func(ik sdkmetric.InstrumentKind) metricdata.Temporality { @@ -50,11 +40,8 @@ func TestMonitoringHandler(t *testing.T) { )) mp := sdkmetric.NewMeterProvider(sdkmetric.WithReader(reader)) - monitoringtest.ClearRegistry(m) c, _ := DefaultContextWithResponseRecorder() - Apply(MonitoringMiddleware(m, mp), h)(c) - equal, result := monitoringtest.CompareMonitoringInt(expected, m) - assert.True(t, equal, result) + Apply(MonitoringMiddleware("", mp), h)(c) monitoringtest.ExpectOtelMetrics(t, reader, expectedOtel) } @@ -62,99 +49,123 @@ func TestMonitoringHandler(t *testing.T) { t.Run("Error", func(t *testing.T) { checkMonitoring(t, Handler403, - map[request.ResultID]int{ - request.IDRequestCount: 1, - request.IDResponseCount: 1, - request.IDResponseErrorsCount: 1, - request.IDResponseErrorsForbidden: 1, - }, map[string]interface{}{ "http.server." + string(request.IDRequestCount): 1, "http.server." + string(request.IDResponseCount): 1, "http.server." + string(request.IDResponseErrorsCount): 1, "http.server." + string(request.IDResponseErrorsForbidden): 1, + string(request.IDRequestCount): 1, + string(request.IDResponseCount): 1, + string(request.IDResponseErrorsCount): 1, + string(request.IDResponseErrorsForbidden): 1, "http.server.request.duration": 1, }, - mockMonitoring, ) }) t.Run("Accepted", func(t *testing.T) { checkMonitoring(t, Handler202, - map[request.ResultID]int{ - request.IDRequestCount: 1, - request.IDResponseCount: 1, - request.IDResponseValidCount: 1, - request.IDResponseValidAccepted: 1, - }, map[string]interface{}{ "http.server." + string(request.IDRequestCount): 1, "http.server." + string(request.IDResponseCount): 1, "http.server." + string(request.IDResponseValidCount): 1, "http.server." + string(request.IDResponseValidAccepted): 1, + string(request.IDRequestCount): 1, + string(request.IDResponseCount): 1, + string(request.IDResponseValidCount): 1, + string(request.IDResponseValidAccepted): 1, "http.server.request.duration": 1, }, - mockMonitoring, ) }) t.Run("Idle", func(t *testing.T) { checkMonitoring(t, HandlerIdle, - map[request.ResultID]int{ - request.IDRequestCount: 1, - request.IDResponseCount: 1, - request.IDResponseValidCount: 1, - request.IDUnset: 1, - }, map[string]interface{}{ "http.server." + string(request.IDRequestCount): 1, "http.server." + string(request.IDResponseCount): 1, "http.server." + string(request.IDResponseValidCount): 1, "http.server." + string(request.IDUnset): 1, + string(request.IDRequestCount): 1, + string(request.IDResponseCount): 1, + string(request.IDResponseValidCount): 1, + string(request.IDUnset): 1, "http.server.request.duration": 1, }, - mockMonitoring, ) }) t.Run("Panic", func(t *testing.T) { checkMonitoring(t, Apply(RecoverPanicMiddleware(), HandlerPanic), - map[request.ResultID]int{ - request.IDRequestCount: 1, - request.IDResponseCount: 1, - request.IDResponseErrorsCount: 1, - request.IDResponseErrorsInternal: 1, - }, map[string]interface{}{ "http.server." + string(request.IDRequestCount): 1, "http.server." + string(request.IDResponseCount): 1, "http.server." + string(request.IDResponseErrorsCount): 1, "http.server." + string(request.IDResponseErrorsInternal): 1, + string(request.IDRequestCount): 1, + string(request.IDResponseCount): 1, + string(request.IDResponseErrorsCount): 1, + string(request.IDResponseErrorsInternal): 1, "http.server.request.duration": 1, }, - mockMonitoring) + ) }) t.Run("Nil", func(t *testing.T) { checkMonitoring(t, HandlerIdle, - map[request.ResultID]int{}, map[string]interface{}{ "http.server." + string(request.IDRequestCount): 1, "http.server." + string(request.IDResponseCount): 1, "http.server." + string(request.IDResponseValidCount): 1, "http.server." + string(request.IDUnset): 1, + string(request.IDRequestCount): 1, + string(request.IDResponseCount): 1, + string(request.IDResponseValidCount): 1, + string(request.IDUnset): 1, "http.server.request.duration": 1, }, - mockMonitoringNil, ) }) + + t.Run("Parallel", func(t *testing.T) { + const i = 3 + reader := sdkmetric.NewManualReader(sdkmetric.WithTemporalitySelector( + func(ik sdkmetric.InstrumentKind) metricdata.Temporality { + return metricdata.DeltaTemporality + }, + )) + mp := sdkmetric.NewMeterProvider(sdkmetric.WithReader(reader)) + m := MonitoringMiddleware("", mp) + c, _ := DefaultContextWithResponseRecorder() + var wg sync.WaitGroup + for range i { + wg.Add(1) + go func() { + Apply(m, HandlerIdle)(c) + wg.Done() + }() + } + wg.Wait() + monitoringtest.ExpectOtelMetrics(t, reader, map[string]interface{}{ + "http.server." + string(request.IDRequestCount): i, + "http.server." + string(request.IDResponseCount): i, + "http.server." + string(request.IDResponseValidCount): i, + "http.server." + string(request.IDUnset): i, + string(request.IDRequestCount): i, + string(request.IDResponseCount): i, + string(request.IDResponseValidCount): i, + string(request.IDUnset): i, + + "http.server.request.duration": i, + }) + }) } diff --git a/internal/beater/middleware/timeout_middleware_test.go b/internal/beater/middleware/timeout_middleware_test.go deleted file mode 100644 index 6690c25e6b8..00000000000 --- a/internal/beater/middleware/timeout_middleware_test.go +++ /dev/null @@ -1,71 +0,0 @@ -// Licensed to Elasticsearch B.V. under one or more contributor -// license agreements. See the NOTICE file distributed with -// this work for additional information regarding copyright -// ownership. Elasticsearch B.V. licenses this file to you under -// the Apache License, Version 2.0 (the "License"); you may -// not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -package middleware - -import ( - "context" - "net/http" - "net/http/httptest" - "testing" - "time" - - "github.com/stretchr/testify/assert" - - "github.com/elastic/apm-server/internal/beater/request" -) - -func TestTimeoutMiddleware(t *testing.T) { - test := func(t *testing.T, handler request.Handler) { - var err error - h, err := TimeoutMiddleware()(handler) - assert.NoError(t, err) - - c := request.NewContext() - r, err := http.NewRequest("GET", "/", nil) - assert.NoError(t, err) - c.Reset(httptest.NewRecorder(), r) - h(c) - - assert.Equal(t, http.StatusServiceUnavailable, c.Result.StatusCode) - } - t.Run("Cancelled", func(t *testing.T) { - test(t, request.Handler(func(c *request.Context) { - ctx := c.Request.Context() - ctx, cancel := context.WithCancel(ctx) - r := c.Request.WithContext(ctx) - c.Request = r - cancel() - })) - }) - t.Run("DeadlineExceeded", func(t *testing.T) { - var cancel func() - defer func() { - if cancel != nil { - cancel() - } - }() - test(t, request.Handler(func(c *request.Context) { - timeout := 1 * time.Nanosecond - ctx := c.Request.Context() - ctx, cancel = context.WithTimeout(ctx, timeout) - r := c.Request.WithContext(ctx) - c.Request = r - <-ctx.Done() // let the context expire - })) - }) -} diff --git a/internal/beater/monitoringtest/monitoring.go b/internal/beater/monitoringtest/monitoring.go deleted file mode 100644 index 36949282511..00000000000 --- a/internal/beater/monitoringtest/monitoring.go +++ /dev/null @@ -1,78 +0,0 @@ -// Licensed to Elasticsearch B.V. under one or more contributor -// license agreements. See the NOTICE file distributed with -// this work for additional information regarding copyright -// ownership. Elasticsearch B.V. licenses this file to you under -// the Apache License, Version 2.0 (the "License"); you may -// not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -package monitoringtest - -import ( - "fmt" - - "github.com/elastic/elastic-agent-libs/monitoring" - - "github.com/elastic/apm-server/internal/beater/request" -) - -// TODO(axw) consider moving these to the middleware package, -// and removing their use in other packages. We should only -// need to check specific values in one place, and elsewhere -// we might want to check that the middleware is installed by -// checking that the middleware has done _something_. - -// CompareMonitoringInt matches expected with real monitoring counters and -// returns false and an a string showind diffs if not matching. -// -// The caller is expected to call ClearRegistry before invoking some code -// path that should update monitoring counters. -func CompareMonitoringInt( - expected map[request.ResultID]int, - m map[request.ResultID]*monitoring.Int, -) (bool, string) { - var result string - for _, id := range allRequestResultIDs() { - monitoringIntVal := int64(0) - monitoringInt := m[id] - if monitoringInt != nil { - monitoringIntVal = monitoringInt.Get() - } - expectedVal := int64(0) - if val, included := expected[id]; included { - expectedVal = int64(val) - } - if expectedVal != monitoringIntVal { - result += fmt.Sprintf("[%s] Expected: %d, Received: %d", id, expectedVal, monitoringIntVal) - } - } - return len(result) == 0, result -} - -// allRequestResultIDs returns all registered request.ResultIDs (needs to be manually maintained) -func allRequestResultIDs() []request.ResultID { - var ids []request.ResultID - for k := range request.MapResultIDToStatus { - ids = append(ids, k) - } - return ids -} - -// ClearRegistry sets all counters to 0 and removes all registered counters from the registry -// Only use this in test environments -func ClearRegistry(m map[request.ResultID]*monitoring.Int) { - for _, i := range m { - if i != nil { - i.Set(0) - } - } -} diff --git a/internal/beater/monitoringtest/opentelemetry.go b/internal/beater/monitoringtest/opentelemetry.go index 54d355a78a6..33a60c4f135 100644 --- a/internal/beater/monitoringtest/opentelemetry.go +++ b/internal/beater/monitoringtest/opentelemetry.go @@ -26,21 +26,55 @@ import ( "go.opentelemetry.io/otel/sdk/metric/metricdata" ) -func ExpectOtelMetrics(t *testing.T, reader sdkmetric.Reader, expectedMetrics map[string]interface{}) { +func ExpectOtelMetrics(t *testing.T, reader sdkmetric.Reader, expectedMetrics map[string]any) { + assertOtelMetrics(t, reader, expectedMetrics, true, true) +} + +func ExpectContainOtelMetrics(t *testing.T, reader sdkmetric.Reader, expectedMetrics map[string]any) { + assertOtelMetrics(t, reader, expectedMetrics, false, true) +} + +func ExpectContainOtelMetricsKeys(t *testing.T, reader sdkmetric.Reader, expectedMetricsKeys []string) { + expectedMetrics := make(map[string]any) + for _, metricKey := range expectedMetricsKeys { + expectedMetrics[metricKey] = nil + } + assertOtelMetrics(t, reader, expectedMetrics, false, false) +} + +func assertOtelMetrics(t *testing.T, reader sdkmetric.Reader, expectedMetrics map[string]any, match, matchVal bool) { t.Helper() var rm metricdata.ResourceMetrics assert.NoError(t, reader.Collect(context.Background(), &rm)) assert.NotEqual(t, 0, len(rm.ScopeMetrics)) - foundMetrics := []string{} + var foundMetrics []string for _, sm := range rm.ScopeMetrics { - for _, m := range sm.Metrics { switch d := m.Data.(type) { + case metricdata.Gauge[int64]: + assert.Equal(t, 1, len(d.DataPoints)) + foundMetrics = append(foundMetrics, m.Name) + if !matchVal { + continue + } + + if v, ok := expectedMetrics[m.Name]; ok { + if dp, ok := v.(int); ok { + assert.Equal(t, int64(dp), d.DataPoints[0].Value, m.Name) + } else { + assert.Fail(t, "expected an int value", m.Name) + } + } else if match { + assert.Fail(t, "unexpected metric", m.Name) + } case metricdata.Sum[int64]: assert.Equal(t, 1, len(d.DataPoints)) foundMetrics = append(foundMetrics, m.Name) + if !matchVal { + continue + } if v, ok := expectedMetrics[m.Name]; ok { if dp, ok := v.(int); ok { @@ -48,12 +82,15 @@ func ExpectOtelMetrics(t *testing.T, reader sdkmetric.Reader, expectedMetrics ma } else { assert.Fail(t, "expected an int value", m.Name) } - } else { + } else if match { assert.Fail(t, "unexpected metric", m.Name) } case metricdata.Histogram[int64]: assert.Equal(t, 1, len(d.DataPoints)) foundMetrics = append(foundMetrics, m.Name) + if !matchVal { + continue + } if v, ok := expectedMetrics[m.Name]; ok { if dp, ok := v.(int); ok { @@ -61,16 +98,20 @@ func ExpectOtelMetrics(t *testing.T, reader sdkmetric.Reader, expectedMetrics ma } else { assert.Fail(t, "expected an int value", m.Name) } - } else { + } else if match { assert.Fail(t, "unexpected metric", m.Name) } } } } - expectedMetricsKeys := []string{} + var expectedMetricsKeys []string for k := range expectedMetrics { expectedMetricsKeys = append(expectedMetricsKeys, k) } - assert.ElementsMatch(t, expectedMetricsKeys, foundMetrics) + if match { + assert.ElementsMatch(t, expectedMetricsKeys, foundMetrics) + } else { + assert.Subset(t, foundMetrics, expectedMetricsKeys) + } } diff --git a/internal/beater/otlp/common.go b/internal/beater/otlp/common.go deleted file mode 100644 index aab2d588cf9..00000000000 --- a/internal/beater/otlp/common.go +++ /dev/null @@ -1,60 +0,0 @@ -// Licensed to Elasticsearch B.V. under one or more contributor -// license agreements. See the NOTICE file distributed with -// this work for additional information regarding copyright -// ownership. Elasticsearch B.V. licenses this file to you under -// the Apache License, Version 2.0 (the "License"); you may -// not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -package otlp - -import ( - "sync" - - "github.com/elastic/apm-data/input/otlp" - "github.com/elastic/apm-server/internal/beater/request" - "github.com/elastic/elastic-agent-libs/monitoring" -) - -var ( - monitoringKeys = append(request.DefaultResultIDs, - request.IDResponseErrorsRateLimit, - request.IDResponseErrorsTimeout, - request.IDResponseErrorsUnauthorized, - ) -) - -type monitoredConsumer struct { - mu sync.RWMutex - consumer *otlp.Consumer -} - -func (m *monitoredConsumer) set(c *otlp.Consumer) { - m.mu.Lock() - defer m.mu.Unlock() - m.consumer = c -} - -func (m *monitoredConsumer) collect(mode monitoring.Mode, V monitoring.Visitor) { - V.OnRegistryStart() - defer V.OnRegistryFinished() - - m.mu.RLock() - c := m.consumer - m.mu.RUnlock() - if c == nil { - return - } - - stats := c.Stats() - monitoring.ReportInt(V, "unsupported_dropped", stats.UnsupportedMetricsDropped) -} diff --git a/internal/beater/otlp/grpc.go b/internal/beater/otlp/grpc.go index 2684e1bd398..512c15bfee6 100644 --- a/internal/beater/otlp/grpc.go +++ b/internal/beater/otlp/grpc.go @@ -23,45 +23,16 @@ import ( "go.opentelemetry.io/collector/pdata/plog/plogotlp" "go.opentelemetry.io/collector/pdata/pmetric/pmetricotlp" "go.opentelemetry.io/collector/pdata/ptrace/ptraceotlp" + "go.opentelemetry.io/otel/metric" "go.uber.org/zap" "google.golang.org/grpc" - "github.com/elastic/elastic-agent-libs/monitoring" - "github.com/elastic/apm-data/input" "github.com/elastic/apm-data/input/otlp" "github.com/elastic/apm-data/model/modelpb" - "github.com/elastic/apm-server/internal/beater/interceptors" - "github.com/elastic/apm-server/internal/beater/request" -) - -var ( - gRPCMetricsRegistry = monitoring.Default.NewRegistry("apm-server.otlp.grpc.metrics") - gRPCMetricsMonitoringMap = request.MonitoringMapForRegistry(gRPCMetricsRegistry, monitoringKeys) - gRPCTracesRegistry = monitoring.Default.NewRegistry("apm-server.otlp.grpc.traces") - gRPCTracesMonitoringMap = request.MonitoringMapForRegistry(gRPCTracesRegistry, monitoringKeys) - gRPCLogsRegistry = monitoring.Default.NewRegistry("apm-server.otlp.grpc.logs") - gRPCLogsMonitoringMap = request.MonitoringMapForRegistry(gRPCLogsRegistry, monitoringKeys) - - gRPCMonitoredConsumer monitoredConsumer ) -func init() { - monitoring.NewFunc(gRPCMetricsRegistry, "consumer", gRPCMonitoredConsumer.collect, monitoring.Report) - - interceptors.RegisterMethodUnaryRequestMetrics( - "/opentelemetry.proto.collector.metrics.v1.MetricsService/Export", - gRPCMetricsMonitoringMap, - ) - interceptors.RegisterMethodUnaryRequestMetrics( - "/opentelemetry.proto.collector.trace.v1.TraceService/Export", - gRPCTracesMonitoringMap, - ) - interceptors.RegisterMethodUnaryRequestMetrics( - "/opentelemetry.proto.collector.logs.v1.LogsService/Export", - gRPCLogsMonitoringMap, - ) -} +var unsupportedGRPCMetricRegistration metric.Registration // RegisterGRPCServices registers OTLP consumer services with the given gRPC server. func RegisterGRPCServices( @@ -69,6 +40,7 @@ func RegisterGRPCServices( logger *zap.Logger, processor modelpb.BatchProcessor, semaphore input.Semaphore, + mp metric.MeterProvider, ) { // TODO(axw) stop assuming we have only one OTLP gRPC service running // at any time, and instead aggregate metrics from consumers that are @@ -79,7 +51,24 @@ func RegisterGRPCServices( Semaphore: semaphore, RemapOTelMetrics: true, }) - gRPCMonitoredConsumer.set(consumer) + + meter := mp.Meter("github.com/elastic/apm-server/internal/beater/otlp") + grpcMetricsConsumerUnsupportedDropped, _ := meter.Int64ObservableCounter( + "apm-server.otlp.grpc.metrics.consumer.unsupported_dropped", + ) + + // TODO we should add an otel counter metric directly in the + // apm-data consumer, then we could get rid of the callback. + if unsupportedGRPCMetricRegistration != nil { + unsupportedGRPCMetricRegistration.Unregister() + } + unsupportedGRPCMetricRegistration, _ = meter.RegisterCallback(func(ctx context.Context, o metric.Observer) error { + stats := consumer.Stats() + if stats.UnsupportedMetricsDropped > 0 { + o.ObserveInt64(grpcMetricsConsumerUnsupportedDropped, stats.UnsupportedMetricsDropped) + } + return nil + }, grpcMetricsConsumerUnsupportedDropped) ptraceotlp.RegisterGRPCServer(grpcServer, &tracesService{consumer: consumer}) pmetricotlp.RegisterGRPCServer(grpcServer, &metricsService{consumer: consumer}) diff --git a/internal/beater/otlp/grpc_test.go b/internal/beater/otlp/grpc_test.go index 5d4e70ad871..2182c035876 100644 --- a/internal/beater/otlp/grpc_test.go +++ b/internal/beater/otlp/grpc_test.go @@ -31,6 +31,9 @@ import ( "go.opentelemetry.io/collector/pdata/pmetric/pmetricotlp" "go.opentelemetry.io/collector/pdata/ptrace" "go.opentelemetry.io/collector/pdata/ptrace/ptraceotlp" + "go.opentelemetry.io/otel/metric" + sdkmetric "go.opentelemetry.io/otel/sdk/metric" + "go.opentelemetry.io/otel/sdk/metric/metricdata" "go.uber.org/zap" "golang.org/x/sync/semaphore" "google.golang.org/grpc" @@ -39,9 +42,9 @@ import ( "github.com/elastic/apm-data/model/modelpb" "github.com/elastic/apm-server/internal/beater/interceptors" + "github.com/elastic/apm-server/internal/beater/monitoringtest" "github.com/elastic/apm-server/internal/beater/otlp" "github.com/elastic/elastic-agent-libs/logp" - "github.com/elastic/elastic-agent-libs/monitoring" ) func TestConsumeTracesGRPC(t *testing.T) { @@ -52,7 +55,14 @@ func TestConsumeTracesGRPC(t *testing.T) { return reportError } - conn := newGRPCServer(t, batchProcessor) + reader := sdkmetric.NewManualReader(sdkmetric.WithTemporalitySelector( + func(ik sdkmetric.InstrumentKind) metricdata.Temporality { + return metricdata.DeltaTemporality + }, + )) + mp := sdkmetric.NewMeterProvider(sdkmetric.WithReader(reader)) + + conn := newGRPCServer(t, batchProcessor, mp) client := ptraceotlp.NewGRPCClient(conn) // Send a minimal trace to verify that everything is connected properly. @@ -77,19 +87,12 @@ func TestConsumeTracesGRPC(t *testing.T) { assert.Len(t, batches[0], 1) assert.Len(t, batches[1], 1) - actual := map[string]interface{}{} - monitoring.GetRegistry("apm-server.otlp.grpc.traces").Do(monitoring.Full, func(key string, value interface{}) { - actual[key] = value + monitoringtest.ExpectContainOtelMetrics(t, reader, map[string]any{ + "apm-server.otlp.grpc.traces.request.count": 2, + "apm-server.otlp.grpc.traces.response.valid.count": 1, + "apm-server.otlp.grpc.traces.response.count": 2, + "apm-server.otlp.grpc.traces.response.errors.count": 1, }) - assert.Equal(t, map[string]interface{}{ - "request.count": int64(2), - "response.count": int64(2), - "response.errors.count": int64(1), - "response.valid.count": int64(1), - "response.errors.ratelimit": int64(0), - "response.errors.timeout": int64(0), - "response.errors.unauthorized": int64(0), - }, actual) } func TestConsumeMetricsGRPC(t *testing.T) { @@ -98,7 +101,14 @@ func TestConsumeMetricsGRPC(t *testing.T) { return reportError } - conn := newGRPCServer(t, batchProcessor) + reader := sdkmetric.NewManualReader(sdkmetric.WithTemporalitySelector( + func(ik sdkmetric.InstrumentKind) metricdata.Temporality { + return metricdata.DeltaTemporality + }, + )) + mp := sdkmetric.NewMeterProvider(sdkmetric.WithReader(reader)) + + conn := newGRPCServer(t, batchProcessor, mp) client := pmetricotlp.NewGRPCClient(conn) // Send a minimal metric to verify that everything is connected properly. @@ -122,21 +132,12 @@ func TestConsumeMetricsGRPC(t *testing.T) { errStatus := status.Convert(err) assert.Equal(t, "failed to publish events", errStatus.Message()) - actual := map[string]interface{}{} - monitoring.GetRegistry("apm-server.otlp.grpc.metrics").Do(monitoring.Full, func(key string, value interface{}) { - actual[key] = value + monitoringtest.ExpectContainOtelMetrics(t, reader, map[string]any{ + "apm-server.otlp.grpc.metrics.request.count": 2, + "apm-server.otlp.grpc.metrics.response.valid.count": 1, + "apm-server.otlp.grpc.metrics.response.count": 2, + "apm-server.otlp.grpc.metrics.response.errors.count": 1, }) - assert.Equal(t, map[string]interface{}{ - "consumer.unsupported_dropped": int64(0), - - "request.count": int64(2), - "response.count": int64(2), - "response.errors.count": int64(1), - "response.valid.count": int64(1), - "response.errors.ratelimit": int64(0), - "response.errors.timeout": int64(0), - "response.errors.unauthorized": int64(0), - }, actual) } func TestConsumeLogsGRPC(t *testing.T) { @@ -147,7 +148,14 @@ func TestConsumeLogsGRPC(t *testing.T) { return reportError } - conn := newGRPCServer(t, batchProcessor) + reader := sdkmetric.NewManualReader(sdkmetric.WithTemporalitySelector( + func(ik sdkmetric.InstrumentKind) metricdata.Temporality { + return metricdata.DeltaTemporality + }, + )) + mp := sdkmetric.NewMeterProvider(sdkmetric.WithReader(reader)) + + conn := newGRPCServer(t, batchProcessor, mp) client := plogotlp.NewGRPCClient(conn) // Send a minimal log record to verify that everything is connected properly. @@ -171,28 +179,21 @@ func TestConsumeLogsGRPC(t *testing.T) { assert.Len(t, batches[0], 1) assert.Len(t, batches[1], 1) - actual := map[string]interface{}{} - monitoring.GetRegistry("apm-server.otlp.grpc.logs").Do(monitoring.Full, func(key string, value interface{}) { - actual[key] = value + monitoringtest.ExpectContainOtelMetrics(t, reader, map[string]any{ + "apm-server.otlp.grpc.logs.request.count": 2, + "apm-server.otlp.grpc.logs.response.valid.count": 1, + "apm-server.otlp.grpc.logs.response.count": 2, + "apm-server.otlp.grpc.logs.response.errors.count": 1, }) - assert.Equal(t, map[string]interface{}{ - "request.count": int64(2), - "response.count": int64(2), - "response.errors.count": int64(1), - "response.valid.count": int64(1), - "response.errors.ratelimit": int64(0), - "response.errors.timeout": int64(0), - "response.errors.unauthorized": int64(0), - }, actual) } -func newGRPCServer(t *testing.T, batchProcessor modelpb.BatchProcessor) *grpc.ClientConn { +func newGRPCServer(t *testing.T, batchProcessor modelpb.BatchProcessor, mp metric.MeterProvider) *grpc.ClientConn { lis, err := net.Listen("tcp", "localhost:0") require.NoError(t, err) logger := logp.NewLogger("otlp.grpc.test") - srv := grpc.NewServer(grpc.UnaryInterceptor(interceptors.Metrics(logger, nil))) + srv := grpc.NewServer(grpc.UnaryInterceptor(interceptors.Metrics(logger, mp))) semaphore := semaphore.NewWeighted(1) - otlp.RegisterGRPCServices(srv, zap.NewNop(), batchProcessor, semaphore) + otlp.RegisterGRPCServices(srv, zap.NewNop(), batchProcessor, semaphore, mp) go srv.Serve(lis) t.Cleanup(srv.GracefulStop) diff --git a/internal/beater/otlp/http.go b/internal/beater/otlp/http.go index 5600ea5dd62..597c535448d 100644 --- a/internal/beater/otlp/http.go +++ b/internal/beater/otlp/http.go @@ -18,6 +18,7 @@ package otlp import ( + "context" "fmt" "io" "net/http" @@ -25,6 +26,7 @@ import ( "go.opentelemetry.io/collector/pdata/plog/plogotlp" "go.opentelemetry.io/collector/pdata/pmetric/pmetricotlp" "go.opentelemetry.io/collector/pdata/ptrace/ptraceotlp" + "go.opentelemetry.io/otel/metric" "go.uber.org/zap" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" @@ -33,26 +35,11 @@ import ( "github.com/elastic/apm-data/input" "github.com/elastic/apm-data/input/otlp" "github.com/elastic/apm-data/model/modelpb" - "github.com/elastic/apm-server/internal/beater/request" - "github.com/elastic/elastic-agent-libs/monitoring" ) -var ( - httpMetricsRegistry = monitoring.Default.NewRegistry("apm-server.otlp.http.metrics") - HTTPMetricsMonitoringMap = request.MonitoringMapForRegistry(httpMetricsRegistry, monitoringKeys) - httpTracesRegistry = monitoring.Default.NewRegistry("apm-server.otlp.http.traces") - HTTPTracesMonitoringMap = request.MonitoringMapForRegistry(httpTracesRegistry, monitoringKeys) - httpLogsRegistry = monitoring.Default.NewRegistry("apm-server.otlp.http.logs") - HTTPLogsMonitoringMap = request.MonitoringMapForRegistry(httpLogsRegistry, monitoringKeys) +var unsupportedHTTPMetricRegistration metric.Registration - httpMonitoredConsumer monitoredConsumer -) - -func init() { - monitoring.NewFunc(httpMetricsRegistry, "consumer", httpMonitoredConsumer.collect, monitoring.Report) -} - -func NewHTTPHandlers(logger *zap.Logger, processor modelpb.BatchProcessor, semaphore input.Semaphore) HTTPHandlers { +func NewHTTPHandlers(logger *zap.Logger, processor modelpb.BatchProcessor, semaphore input.Semaphore, mp metric.MeterProvider) HTTPHandlers { // TODO(axw) stop assuming we have only one OTLP HTTP consumer running // at any time, and instead aggregate metrics from consumers that are // dynamically registered and unregistered. @@ -62,7 +49,25 @@ func NewHTTPHandlers(logger *zap.Logger, processor modelpb.BatchProcessor, semap Semaphore: semaphore, RemapOTelMetrics: true, }) - httpMonitoredConsumer.set(consumer) + + meter := mp.Meter("github.com/elastic/apm-server/internal/beater/otlp") + httpMetricsConsumerUnsupportedDropped, _ := meter.Int64ObservableCounter( + "apm-server.otlp.http.metrics.consumer.unsupported_dropped", + ) + + // TODO we should add an otel counter metric directly in the + // apm-data consumer, then we could get rid of the callback. + if unsupportedHTTPMetricRegistration != nil { + unsupportedHTTPMetricRegistration.Unregister() + } + unsupportedHTTPMetricRegistration, _ = meter.RegisterCallback(func(ctx context.Context, o metric.Observer) error { + stats := consumer.Stats() + if stats.UnsupportedMetricsDropped > 0 { + o.ObserveInt64(httpMetricsConsumerUnsupportedDropped, stats.UnsupportedMetricsDropped) + } + return nil + }, httpMetricsConsumerUnsupportedDropped) + return HTTPHandlers{consumer: consumer} } diff --git a/internal/beater/otlp/http_test.go b/internal/beater/otlp/http_test.go index 93702049759..93ab0d32ce0 100644 --- a/internal/beater/otlp/http_test.go +++ b/internal/beater/otlp/http_test.go @@ -33,6 +33,8 @@ import ( "go.opentelemetry.io/collector/pdata/pmetric/pmetricotlp" "go.opentelemetry.io/collector/pdata/ptrace" "go.opentelemetry.io/collector/pdata/ptrace/ptraceotlp" + sdkmetric "go.opentelemetry.io/otel/sdk/metric" + "go.opentelemetry.io/otel/sdk/metric/metricdata" "golang.org/x/sync/semaphore" "github.com/elastic/apm-data/model/modelpb" @@ -40,8 +42,8 @@ import ( "github.com/elastic/apm-server/internal/beater/api" "github.com/elastic/apm-server/internal/beater/auth" "github.com/elastic/apm-server/internal/beater/config" + "github.com/elastic/apm-server/internal/beater/monitoringtest" "github.com/elastic/apm-server/internal/beater/ratelimit" - "github.com/elastic/elastic-agent-libs/monitoring" ) func TestConsumeTracesHTTP(t *testing.T) { @@ -52,7 +54,7 @@ func TestConsumeTracesHTTP(t *testing.T) { return reportError } - addr := newHTTPServer(t, batchProcessor) + addr, reader := newHTTPServer(t, batchProcessor) // Send a minimal trace to verify that everything is connected properly. // @@ -75,19 +77,12 @@ func TestConsumeTracesHTTP(t *testing.T) { require.Len(t, batches, 1) assert.Len(t, batches[0], 1) - actual := map[string]interface{}{} - monitoring.GetRegistry("apm-server.otlp.http.traces").Do(monitoring.Full, func(key string, value interface{}) { - actual[key] = value + monitoringtest.ExpectContainOtelMetrics(t, reader, map[string]any{ + "http.server.request.count": 1, + "http.server.response.count": 1, + "http.server.response.valid.count": 1, }) - assert.Equal(t, map[string]interface{}{ - "request.count": int64(1), - "response.count": int64(1), - "response.errors.count": int64(0), - "response.valid.count": int64(1), - "response.errors.ratelimit": int64(0), - "response.errors.timeout": int64(0), - "response.errors.unauthorized": int64(0), - }, actual) + } func TestConsumeMetricsHTTP(t *testing.T) { @@ -96,7 +91,7 @@ func TestConsumeMetricsHTTP(t *testing.T) { return reportError } - addr := newHTTPServer(t, batchProcessor) + addr, reader := newHTTPServer(t, batchProcessor) // Send a minimal metric to verify that everything is connected properly. // @@ -119,21 +114,11 @@ func TestConsumeMetricsHTTP(t *testing.T) { assert.NoError(t, err) assert.NoError(t, rsp.Body.Close()) - actual := map[string]interface{}{} - monitoring.GetRegistry("apm-server.otlp.http.metrics").Do(monitoring.Full, func(key string, value interface{}) { - actual[key] = value + monitoringtest.ExpectContainOtelMetrics(t, reader, map[string]any{ + "http.server.request.count": 1, + "http.server.response.count": 1, + "http.server.response.valid.count": 1, }) - assert.Equal(t, map[string]interface{}{ - "consumer.unsupported_dropped": int64(0), - - "request.count": int64(1), - "response.count": int64(1), - "response.errors.count": int64(0), - "response.valid.count": int64(1), - "response.errors.ratelimit": int64(0), - "response.errors.timeout": int64(0), - "response.errors.unauthorized": int64(0), - }, actual) } func TestConsumeLogsHTTP(t *testing.T) { @@ -144,7 +129,7 @@ func TestConsumeLogsHTTP(t *testing.T) { return reportError } - addr := newHTTPServer(t, batchProcessor) + addr, reader := newHTTPServer(t, batchProcessor) // Send a minimal log record to verify that everything is connected properly. // @@ -165,24 +150,22 @@ func TestConsumeLogsHTTP(t *testing.T) { assert.NoError(t, rsp.Body.Close()) require.Len(t, batches, 1) - actual := map[string]interface{}{} - monitoring.GetRegistry("apm-server.otlp.http.logs").Do(monitoring.Full, func(key string, value interface{}) { - actual[key] = value + monitoringtest.ExpectContainOtelMetrics(t, reader, map[string]any{ + "http.server.request.count": 1, + "http.server.response.count": 1, + "http.server.response.valid.count": 1, }) - assert.Equal(t, map[string]interface{}{ - "request.count": int64(1), - "response.count": int64(1), - "response.errors.count": int64(0), - "response.valid.count": int64(1), - "response.errors.ratelimit": int64(0), - "response.errors.timeout": int64(0), - "response.errors.unauthorized": int64(0), - }, actual) } -func newHTTPServer(t *testing.T, batchProcessor modelpb.BatchProcessor) string { +func newHTTPServer(t *testing.T, batchProcessor modelpb.BatchProcessor) (string, sdkmetric.Reader) { lis, err := net.Listen("tcp", "localhost:0") require.NoError(t, err) + reader := sdkmetric.NewManualReader(sdkmetric.WithTemporalitySelector( + func(ik sdkmetric.InstrumentKind) metricdata.Temporality { + return metricdata.DeltaTemporality + }, + )) + mp := sdkmetric.NewMeterProvider(sdkmetric.WithReader(reader)) cfg := &config.Config{} auth, _ := auth.NewAuthenticator(cfg.AgentAuth) ratelimitStore, _ := ratelimit.NewStore(1000, 1000, 1000) @@ -190,11 +173,12 @@ func newHTTPServer(t *testing.T, batchProcessor modelpb.BatchProcessor) string { cfg, batchProcessor, auth, - agentcfg.NewDirectFetcher(nil), + agentcfg.NewEmptyFetcher(), ratelimitStore, nil, func() bool { return true }, semaphore.NewWeighted(1), + mp, ) require.NoError(t, err) srv := http.Server{Handler: router} @@ -202,5 +186,5 @@ func newHTTPServer(t *testing.T, batchProcessor modelpb.BatchProcessor) string { require.NoError(t, srv.Close()) }) go srv.Serve(lis) - return lis.Addr().String() + return lis.Addr().String(), reader } diff --git a/internal/beater/processors.go b/internal/beater/processors.go index dd57b430ed0..1438de0f363 100644 --- a/internal/beater/processors.go +++ b/internal/beater/processors.go @@ -79,7 +79,7 @@ func newObserverBatchProcessor() modelpb.ProcessBatchFunc { observer := (*b)[i].Observer observer.Hostname = hostname observer.Type = "apm-server" - observer.Version = version.Version + observer.Version = version.VersionWithQualifier() } return nil } diff --git a/internal/beater/request/context.go b/internal/beater/request/context.go index 636efe82fb1..56541605757 100644 --- a/internal/beater/request/context.go +++ b/internal/beater/request/context.go @@ -20,7 +20,9 @@ package request import ( "compress/gzip" "compress/zlib" + "context" "encoding/json" + "errors" "io" "net/http" "net/netip" @@ -42,6 +44,7 @@ const ( var ( mimeTypesJSON = []string{mimeTypeAny, mimeTypeApplicationJSON} + errTimeout = errors.New("request timed out") ) type zlibReadCloseResetter interface { @@ -189,6 +192,14 @@ func (c *Context) WriteResult() { } c.writeAttempts++ + // Before writing the result check for client timeout. + // In case it happened override the result with timeout error. + if err := c.Request.Context().Err(); errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) { + c.Result.SetDefault(IDResponseErrorsTimeout) + c.Result.Err = errTimeout + c.Result.Body = errTimeout.Error() + } + c.ResponseWriter.Header().Set(headers.XContentTypeOptions, "nosniff") body := c.Result.Body diff --git a/internal/beater/request/result.go b/internal/beater/request/result.go index a69117a9cfc..2f03298e2a9 100644 --- a/internal/beater/request/result.go +++ b/internal/beater/request/result.go @@ -20,8 +20,6 @@ package request import ( "net/http" - "github.com/elastic/elastic-agent-libs/monitoring" - "github.com/pkg/errors" ) @@ -101,9 +99,6 @@ var ( IDResponseErrorsServiceUnavailable: {Code: http.StatusServiceUnavailable, Keyword: "service unavailable"}, IDResponseErrorsInternal: {Code: http.StatusInternalServerError, Keyword: "internal error"}, } - - // DefaultResultIDs is a list of the default result IDs used by the package. - DefaultResultIDs = []ResultID{IDRequestCount, IDResponseCount, IDResponseErrorsCount, IDResponseValidCount} ) // ResultID unique string identifying a requests Result @@ -125,27 +120,6 @@ type Result struct { Stacktrace string } -// DefaultMonitoringMapForRegistry returns map matching resultIDs to monitoring counters for given registry. -func DefaultMonitoringMapForRegistry(r *monitoring.Registry) map[ResultID]*monitoring.Int { - ids := append(DefaultResultIDs, IDUnset) - for id := range MapResultIDToStatus { - ids = append(ids, id) - } - return MonitoringMapForRegistry(r, ids) -} - -// MonitoringMapForRegistry returns map matching resultIDs to monitoring counters for given registry and keys -func MonitoringMapForRegistry(r *monitoring.Registry, ids []ResultID) map[ResultID]*monitoring.Int { - m := map[ResultID]*monitoring.Int{} - counter := func(s ResultID) *monitoring.Int { - return monitoring.NewInt(r, string(s)) - } - for _, id := range ids { - m[id] = counter(id) - } - return m -} - // Reset sets result to it's empty values func (r *Result) Reset() { r.ID = IDUnset diff --git a/internal/beater/request/result_test.go b/internal/beater/request/result_test.go index 88e05e00189..07de0e29cfc 100644 --- a/internal/beater/request/result_test.go +++ b/internal/beater/request/result_test.go @@ -24,8 +24,6 @@ import ( "github.com/stretchr/testify/assert" - "github.com/elastic/elastic-agent-libs/monitoring" - "github.com/pkg/errors" ) @@ -188,22 +186,3 @@ func TestResult_Failure(t *testing.T) { assert.True(t, (&Result{StatusCode: http.StatusBadRequest}).Failure()) assert.True(t, (&Result{StatusCode: http.StatusServiceUnavailable}).Failure()) } - -func TestDefaultMonitoringMapForRegistry(t *testing.T) { - mockRegistry := monitoring.NewRegistry().NewRegistry("mock-default") - m := DefaultMonitoringMapForRegistry(mockRegistry) - assert.Equal(t, 22, len(m)) - for id := range m { - assert.Equal(t, int64(0), m[id].Get()) - } -} - -func TestMonitoringMapForRegistry(t *testing.T) { - keys := []ResultID{IDEventDroppedCount, IDResponseErrorsServiceUnavailable} - mockRegistry := monitoring.NewRegistry().NewRegistry("mock-with-keys") - m := MonitoringMapForRegistry(mockRegistry, keys) - assert.Equal(t, 2, len(m)) - for id := range m { - assert.Equal(t, int64(0), m[id].Get()) - } -} diff --git a/internal/beater/server.go b/internal/beater/server.go index 397e21e5064..5f721068b6a 100644 --- a/internal/beater/server.go +++ b/internal/beater/server.go @@ -24,13 +24,13 @@ import ( "go.elastic.co/apm/module/apmgorilla/v2" "go.elastic.co/apm/v2" + "go.opentelemetry.io/otel/metric" "go.uber.org/zap" "golang.org/x/sync/errgroup" "google.golang.org/grpc" "github.com/elastic/beats/v7/libbeat/version" "github.com/elastic/elastic-agent-libs/logp" - "github.com/elastic/elastic-agent-libs/monitoring" "github.com/elastic/apm-data/input" "github.com/elastic/apm-data/model/modelpb" @@ -39,7 +39,6 @@ import ( "github.com/elastic/apm-server/internal/beater/api" "github.com/elastic/apm-server/internal/beater/auth" "github.com/elastic/apm-server/internal/beater/config" - "github.com/elastic/apm-server/internal/beater/jaeger" "github.com/elastic/apm-server/internal/beater/otlp" "github.com/elastic/apm-server/internal/beater/ratelimit" "github.com/elastic/apm-server/internal/elasticsearch" @@ -47,10 +46,6 @@ import ( "github.com/elastic/apm-server/internal/sourcemap" ) -var ( - agentcfgMonitoringRegistry = monitoring.Default.NewRegistry("apm-server.agentcfg") -) - // WrapServerFunc is a function for injecting behaviour into ServerParams // and RunServerFunc. // @@ -86,6 +81,9 @@ type ServerParams struct { // for self-instrumentation. Tracer *apm.Tracer + // MeterProvider is the MeterProvider + MeterProvider metric.MeterProvider + // Authenticator holds an authenticator that can be used for // authenticating clients, and obtaining authentication details // and an auth.Authorizer for authorizing the client for future @@ -181,6 +179,7 @@ func newServer(args ServerParams, listener net.Listener) (server, error) { args.SourcemapFetcher, publishReady, args.Semaphore, + args.MeterProvider, ) if err != nil { return server{}, err @@ -200,8 +199,7 @@ func newServer(args ServerParams, listener net.Listener) (server, error) { } } zapLogger := zap.New(args.Logger.Core(), zap.WithCaller(true)) - otlp.RegisterGRPCServices(args.GRPCServer, zapLogger, otlpBatchProcessor, args.Semaphore) - jaeger.RegisterGRPCServices(args.GRPCServer, zapLogger, args.BatchProcessor, args.AgentConfig, args.Semaphore) + otlp.RegisterGRPCServices(args.GRPCServer, zapLogger, otlpBatchProcessor, args.Semaphore, args.MeterProvider) return server{ logger: args.Logger, @@ -222,11 +220,10 @@ func (s server) run(ctx context.Context) error { }) g.Go(func() error { <-ctx.Done() - // httpServer should stop before grpcServer to avoid a panic caused by placing a new connection into - // a closed grpc connection channel during shutdown. - // See https://github.com/elastic/gmux/issues/13 - s.httpServer.stop() s.grpcServer.GracefulStop() + stopctx, cancel := context.WithTimeout(context.Background(), s.cfg.ShutdownTimeout) + defer cancel() + s.httpServer.stop(stopctx) return nil }) if err := g.Wait(); err != http.ErrServerClosed { @@ -241,20 +238,17 @@ func newAgentConfigFetcher( kibanaClient *kibana.Client, newElasticsearchClient func(*elasticsearch.Config) (*elasticsearch.Client, error), tracer *apm.Tracer, + mp metric.MeterProvider, ) (agentcfg.Fetcher, func(context.Context) error, error) { // Always use ElasticsearchFetcher, and as a fallback, use: // 1. no fallback if Elasticsearch is explicitly configured - // 2. fleet agent config - // 3. kibana fetcher if (2) is not available - // 4. no fallback if both (2) and (3) are not available + // 2. kibana fetcher + // 3. no fallback if (2) is not available var fallbackFetcher agentcfg.Fetcher switch { case cfg.AgentConfig.ESOverrideConfigured: // Disable fallback because agent config Elasticsearch is explicitly configured. - case cfg.FleetAgentConfigs != nil: - agentConfigurations := agentcfg.ConvertAgentConfigs(cfg.FleetAgentConfigs) - fallbackFetcher = agentcfg.NewDirectFetcher(agentConfigurations) case kibanaClient != nil: var err error fallbackFetcher, err = agentcfg.NewKibanaFetcher(kibanaClient, cfg.AgentConfig.Cache.Expiration) @@ -269,8 +263,6 @@ func newAgentConfigFetcher( if err != nil { return nil, nil, err } - esFetcher := agentcfg.NewElasticsearchFetcher(esClient, cfg.AgentConfig.Cache.Expiration, fallbackFetcher, tracer) - agentcfgMonitoringRegistry.Remove("elasticsearch") - monitoring.NewFunc(agentcfgMonitoringRegistry, "elasticsearch", esFetcher.CollectMonitoring, monitoring.Report) + esFetcher := agentcfg.NewElasticsearchFetcher(esClient, cfg.AgentConfig.Cache.Expiration, fallbackFetcher, tracer, mp) return agentcfg.SanitizingFetcher{Fetcher: esFetcher}, esFetcher.Run, nil } diff --git a/internal/beater/server_test.go b/internal/beater/server_test.go index 4540f45f368..d77cd245b58 100644 --- a/internal/beater/server_test.go +++ b/internal/beater/server_test.go @@ -21,6 +21,7 @@ import ( "bytes" "context" "encoding/json" + "errors" "fmt" "io" "net" @@ -36,9 +37,12 @@ import ( "time" "github.com/gogo/protobuf/proto" - "github.com/jaegertracing/jaeger/proto-gen/api_v2" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + sdkmetric "go.opentelemetry.io/otel/sdk/metric" + "go.opentelemetry.io/otel/sdk/metric/metricdata" + "go.uber.org/zap/zapcore" + "go.uber.org/zap/zaptest/observer" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/credentials/insecure" @@ -48,13 +52,15 @@ import ( _ "github.com/elastic/beats/v7/libbeat/outputs/console" _ "github.com/elastic/beats/v7/libbeat/publisher/queue/memqueue" agentconfig "github.com/elastic/elastic-agent-libs/config" - "github.com/elastic/elastic-agent-libs/monitoring" + "github.com/elastic/elastic-agent-libs/logp" "github.com/elastic/apm-data/model/modelpb" "github.com/elastic/apm-server/internal/beater" "github.com/elastic/apm-server/internal/beater/api" "github.com/elastic/apm-server/internal/beater/beatertest" "github.com/elastic/apm-server/internal/beater/config" + "github.com/elastic/apm-server/internal/beater/monitoringtest" + "github.com/elastic/apm-server/internal/beater/request" ) func TestServerOk(t *testing.T) { @@ -281,20 +287,6 @@ func TestServerNoContentType(t *testing.T) { assert.Equal(t, http.StatusAccepted, rsp.StatusCode) } -func TestServerJaegerGRPC(t *testing.T) { - srv := beatertest.NewServer(t) - baseURL, err := url.Parse(srv.URL) - require.NoError(t, err) - conn, err := grpc.NewClient(baseURL.Host, grpc.WithTransportCredentials(insecure.NewCredentials())) - require.NoError(t, err) - defer conn.Close() - - client := api_v2.NewCollectorServiceClient(conn) - result, err := client.PostSpans(context.Background(), &api_v2.PostSpansRequest{}) - assert.NoError(t, err) - assert.NotNil(t, result) -} - func TestServerOTLPGRPC(t *testing.T) { srv := beatertest.NewServer(t, beatertest.WithConfig(agentconfig.MustNewConfigFrom(map[string]interface{}{ "apm-server.auth.secret_token": "abc123", @@ -464,12 +456,14 @@ func TestServerElasticsearchOutput(t *testing.T) { defer elasticsearchServer.Close() defer close(done) - // Pre-create the libbeat registry with some variables that should not - // be reported, as we define our own libbeat metrics registry. - monitoring.Default.Remove("libbeat.whatever") - monitoring.NewInt(monitoring.Default, "libbeat.whatever") + reader := sdkmetric.NewManualReader(sdkmetric.WithTemporalitySelector( + func(ik sdkmetric.InstrumentKind) metricdata.Temporality { + return metricdata.DeltaTemporality + }, + )) + mp := sdkmetric.NewMeterProvider(sdkmetric.WithReader(reader)) - srv := beatertest.NewServer(t, beatertest.WithConfig(agentconfig.MustNewConfigFrom(map[string]interface{}{ + srv := beatertest.NewServer(t, beatertest.WithMeterProvider(mp), beatertest.WithConfig(agentconfig.MustNewConfigFrom(map[string]interface{}{ "output.elasticsearch": map[string]interface{}{ "hosts": []string{elasticsearchServer.URL}, "flush_interval": "1ms", @@ -495,44 +489,11 @@ func TestServerElasticsearchOutput(t *testing.T) { t.Fatal("timed out waiting for bulk request") } - snapshot := monitoring.CollectStructSnapshot(monitoring.Default.GetRegistry("libbeat"), monitoring.Full, false) - assert.Equal(t, map[string]interface{}{ - "output": map[string]interface{}{ - "events": map[string]interface{}{ - "acked": int64(0), - "active": int64(5), - "batches": int64(0), - "failed": int64(0), - "toomany": int64(0), - "total": int64(5), - }, - "type": "elasticsearch", - "write": map[string]interface{}{ - // _bulk requests haven't completed, so bytes flushed won't have been updated. - "bytes": int64(0), - }, - }, - "pipeline": map[string]interface{}{ - "events": map[string]interface{}{ - "total": int64(5), - }, - }, - }, snapshot) - - snapshot = monitoring.CollectStructSnapshot(monitoring.Default.GetRegistry("output"), monitoring.Full, false) - assert.Equal(t, map[string]interface{}{ - "elasticsearch": map[string]interface{}{ - "bulk_requests": map[string]interface{}{ - "available": int64(9), - "completed": int64(0), - }, - "indexers": map[string]interface{}{ - "active": int64(1), - "destroyed": int64(0), - "created": int64(0), - }, - }, - }, snapshot) + monitoringtest.ExpectContainOtelMetrics(t, reader, map[string]any{ + "elasticsearch.events.count": 5, + "elasticsearch.events.queued": 5, + "elasticsearch.bulk_requests.available": 9, + }) } func TestServerPProf(t *testing.T) { @@ -587,6 +548,94 @@ func TestWrapServer(t *testing.T) { require.Equal(t, "true", out["labels"].(map[string]any)["wrapped_reporter"]) } +func TestWrapServerAPMInstrumentationTimeout(t *testing.T) { + // Override ELASTIC_APM_API_REQUEST_TIME to 10ms instead of + // the default 10s to speed up this test time. + t.Setenv("ELASTIC_APM_API_REQUEST_TIME", "10ms") + + // Enable self instrumentation, simulate a client disconnecting when sending intakev2 request + // Check that tracer records the correct http status code + found := make(chan struct{}) + reqCtx, reqCancel := context.WithCancel(context.Background()) + + reader := sdkmetric.NewManualReader(sdkmetric.WithTemporalitySelector( + func(ik sdkmetric.InstrumentKind) metricdata.Temporality { + return metricdata.DeltaTemporality + }, + )) + mp := sdkmetric.NewMeterProvider(sdkmetric.WithReader(reader)) + + escfg, _ := beatertest.ElasticsearchOutputConfig(t) + _ = logp.DevelopmentSetup(logp.ToObserverOutput()) + srv := beatertest.NewServer(t, beatertest.WithMeterProvider(mp), beatertest.WithConfig(escfg, agentconfig.MustNewConfigFrom( + map[string]interface{}{ + "instrumentation.enabled": true, + })), beatertest.WithWrapServer( + func(args beater.ServerParams, runServer beater.RunServerFunc) (beater.ServerParams, beater.RunServerFunc, error) { + args.BatchProcessor = modelpb.ProcessBatchFunc(func(ctx context.Context, batch *modelpb.Batch) error { + // The service name is set to "1234_service-12a3" in the testData file + if len(*batch) > 0 && (*batch)[0].Service.Name == "1234_service-12a3" { + // Simulate a client disconnecting by cancelling the context + reqCancel() + // Wait for the client disconnection to be acknowledged by http server + <-ctx.Done() + assert.ErrorIs(t, ctx.Err(), context.Canceled) + return errors.New("foobar") + } + for _, i := range *batch { + // Perform assertions on the event sent by the apmgorilla tracer + if i.Transaction.Id != "" && i.Transaction.Name == "POST /intake/v2/events" { + assert.Equal(t, "HTTP 5xx", i.Transaction.Result) + assert.Equal(t, http.StatusServiceUnavailable, int(i.Http.Response.StatusCode)) + close(found) + } + } + return nil + }) + return args, runServer, nil + }, + )) + + req, err := http.NewRequestWithContext(reqCtx, http.MethodPost, srv.URL+api.IntakePath, bytes.NewReader(testData)) + require.NoError(t, err) + req.Header.Add("Content-Type", "application/x-ndjson") + resp, err := srv.Client.Do(req) + require.ErrorIs(t, err, context.Canceled) + require.Nil(t, resp) + + select { + case <-time.After(time.Second): // go apm agent takes time to send trace events + assert.Fail(t, "timeout waiting for trace doc") + case <-found: + // Have to wait a bit here to avoid racing on the order of metrics middleware and the batch processor from above. + time.Sleep(10 * time.Millisecond) + } + + // Assert that logs contain expected values: + // - Original error with the status code. + // - Request timeout is logged separately with the the original error status code. + logs := logp.ObserverLogs().Filter(func(l observer.LoggedEntry) bool { + return l.Level == zapcore.ErrorLevel + }).AllUntimed() + assert.Len(t, logs, 1) + assert.Equal(t, logs[0].Message, "request timed out") + for _, f := range logs[0].Context { + switch f.Key { + case "http.response.status_code": + assert.Equal(t, int(f.Integer), http.StatusServiceUnavailable) + case "error.message": + assert.Equal(t, f.String, "request timed out") + } + } + // Assert that metrics have expected response values reported. + monitoringtest.ExpectContainOtelMetrics(t, reader, map[string]any{ + "http.server." + string(request.IDRequestCount): 1, + "http.server." + string(request.IDResponseCount): 1, + "http.server." + string(request.IDResponseErrorsCount): 1, + "http.server." + string(request.IDResponseErrorsTimeout): 1, // test data POST /intake/v2/events + }) +} + var testData = func() []byte { b, err := os.ReadFile("../../testdata/intake-v2/transactions.ndjson") if err != nil { diff --git a/internal/beater/tracing.go b/internal/beater/tracing.go index fdc5cc25211..3d6705299d0 100644 --- a/internal/beater/tracing.go +++ b/internal/beater/tracing.go @@ -21,6 +21,9 @@ import ( "net" "net/http" + "go.opentelemetry.io/otel/metric" + "go.opentelemetry.io/otel/metric/noop" + "github.com/elastic/elastic-agent-libs/logp" "github.com/elastic/apm-data/input" @@ -32,7 +35,7 @@ import ( "github.com/elastic/apm-server/internal/beater/ratelimit" ) -func newTracerServer(cfg *config.Config, listener net.Listener, logger *logp.Logger, batchProcessor modelpb.BatchProcessor, semaphore input.Semaphore) (*http.Server, error) { +func newTracerServer(cfg *config.Config, listener net.Listener, logger *logp.Logger, batchProcessor modelpb.BatchProcessor, semaphore input.Semaphore, mp metric.MeterProvider) (*http.Server, error) { ratelimitStore, err := ratelimit.NewStore(1, 1, 1) // unused, arbitrary params if err != nil { return nil, err @@ -41,16 +44,16 @@ func newTracerServer(cfg *config.Config, listener net.Listener, logger *logp.Log if err != nil { return nil, err } - agentConfigFetcher := agentcfg.SanitizingFetcher{Fetcher: agentcfg.NewDirectFetcher(agentcfg.ConvertAgentConfigs(cfg.FleetAgentConfigs))} mux, err := api.NewMux( cfg, batchProcessor, authenticator, - agentConfigFetcher, + agentcfg.NewEmptyFetcher(), ratelimitStore, nil, // no sourcemap store func() bool { return true }, // ready for publishing semaphore, + noop.NewMeterProvider(), ) if err != nil { return nil, err diff --git a/internal/elasticsearch/client.go b/internal/elasticsearch/client.go index aa7757ca3ae..bb9be3376b5 100644 --- a/internal/elasticsearch/client.go +++ b/internal/elasticsearch/client.go @@ -36,7 +36,7 @@ var retryableStatuses = []int{ http.StatusTooManyRequests, } -var userAgent = fmt.Sprintf("Elastic-APM-Server/%s go-elasticsearch/%s", version.Version, esv8.Version) +var userAgent = fmt.Sprintf("Elastic-APM-Server/%s go-elasticsearch/%s", version.VersionWithQualifier(), esv8.Version) type Client = esv8.Client diff --git a/internal/elasticsearch/client_test.go b/internal/elasticsearch/client_test.go index 4126c879031..d3416a4c8ae 100644 --- a/internal/elasticsearch/client_test.go +++ b/internal/elasticsearch/client_test.go @@ -18,7 +18,7 @@ package elasticsearch import ( - "context" + "bytes" "fmt" "net/http" "net/http/httptest" @@ -30,6 +30,7 @@ import ( apmVersion "github.com/elastic/apm-server/internal/version" esv8 "github.com/elastic/go-elasticsearch/v8" + "github.com/elastic/go-elasticsearch/v8/esapi" ) func TestClient(t *testing.T) { @@ -48,9 +49,11 @@ func TestClient(t *testing.T) { } func TestClientCustomHeaders(t *testing.T) { - var requestHeaders http.Header + wait := make(chan struct{}) srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - requestHeaders = r.Header + w.Header().Set("X-Elastic-Product", "Elasticsearch") + assert.Equal(t, "header", r.Header.Get("custom")) + close(wait) })) defer srv.Close() @@ -61,13 +64,20 @@ func TestClientCustomHeaders(t *testing.T) { client, err := NewClient(&cfg) require.NoError(t, err) - CreateAPIKey(context.Background(), client, CreateAPIKeyRequest{}) - assert.Equal(t, "header", requestHeaders.Get("custom")) + _, err = client.Bulk(bytes.NewReader([]byte("{}"))) + require.NoError(t, err) + select { + case <-wait: + case <-time.After(1 * time.Second): + t.Fatal("timed out while waiting for request") + } + } func TestClientCustomUserAgent(t *testing.T) { wait := make(chan struct{}) srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("X-Elastic-Product", "Elasticsearch") assert.Equal(t, fmt.Sprintf("Elastic-APM-Server/%s go-elasticsearch/%s", apmVersion.Version, esv8.Version), r.Header.Get("User-Agent")) close(wait) })) @@ -79,10 +89,100 @@ func TestClientCustomUserAgent(t *testing.T) { client, err := NewClient(&cfg) require.NoError(t, err) - CreateAPIKey(context.Background(), client, CreateAPIKeyRequest{}) + _, err = client.Bulk(bytes.NewReader([]byte("{}"))) + require.NoError(t, err) select { case <-wait: case <-time.After(1 * time.Second): t.Fatal("timed out while waiting for request") } } + +func esMockHandler(responder http.HandlerFunc) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("X-Elastic-Product", "Elasticsearch") + + switch { + case r.Method == http.MethodPost && r.URL.Path == "/_bulk": + responder(w, r) + return + default: + http.Error(w, "unsupported request", 419) // Signal unexpected error + return + } + } +} + +func TestClientRetryableStatuses(t *testing.T) { + tests := []struct { + name string + responseStatusCode int + expectedStatusCode int + expectedRequestCount int + }{ + { + name: "retry 429 Too Many Requests", + responseStatusCode: http.StatusTooManyRequests, + expectedStatusCode: http.StatusOK, + expectedRequestCount: 2, + }, + { + name: "retry 502 Bad Gateway", + responseStatusCode: http.StatusBadGateway, + expectedStatusCode: http.StatusBadGateway, + expectedRequestCount: 1, + }, + { + name: "retry 503 Service Not Available", + responseStatusCode: http.StatusServiceUnavailable, + expectedStatusCode: http.StatusServiceUnavailable, + expectedRequestCount: 1, + }, + { + name: "retry 504 Gateway Timeout", + responseStatusCode: http.StatusGatewayTimeout, + expectedStatusCode: http.StatusGatewayTimeout, + expectedRequestCount: 1, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + maxRetries := 2 + count := 0 + handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if count < maxRetries { + count += 1 + http.Error(w, "", tt.responseStatusCode) + return + } + + w.WriteHeader(http.StatusOK) + }) + + es := esMockHandler(handler) + srv := httptest.NewServer(&es) + defer srv.Close() + + c := Config{ + Username: "test", + Password: "foobar", + Backoff: BackoffConfig{ + Init: 0, + Max: 0, + }, + MaxRetries: maxRetries, + Hosts: []string{srv.URL}, + } + client, err := NewClient(&c) + require.NoError(t, err) + + var buf bytes.Buffer + var res *esapi.Response + res, err = client.Bulk(bytes.NewReader(buf.Bytes())) + require.NoError(t, err) + assert.Equal(t, tt.expectedStatusCode, res.StatusCode) + assert.Equal(t, tt.expectedRequestCount, count) + }) + } +} diff --git a/internal/elasticsearch/security_api.go b/internal/elasticsearch/security_api.go index 34f66bee9e8..d504f40bb05 100644 --- a/internal/elasticsearch/security_api.go +++ b/internal/elasticsearch/security_api.go @@ -25,35 +25,6 @@ import ( "github.com/elastic/go-elasticsearch/v8/esutil" ) -// CreateAPIKey requires manage_api_key cluster privilege -func CreateAPIKey(ctx context.Context, client *Client, apikeyReq CreateAPIKeyRequest) (CreateAPIKeyResponse, error) { - var apikey CreateAPIKeyResponse - req := esapi.SecurityCreateAPIKeyRequest{Body: esutil.NewJSONReader(apikeyReq)} - err := doRequest(ctx, client, req, &apikey) - return apikey, err -} - -// GetAPIKeys requires manage_api_key cluster privilege -func GetAPIKeys(ctx context.Context, client *Client, apikeyReq GetAPIKeyRequest) (GetAPIKeyResponse, error) { - req := esapi.SecurityGetAPIKeyRequest{} - if apikeyReq.ID != nil { - req.ID = *apikeyReq.ID - } else if apikeyReq.Name != nil { - req.Name = *apikeyReq.Name - } - var apikey GetAPIKeyResponse - err := doRequest(ctx, client, req, &apikey) - return apikey, err -} - -// InvalidateAPIKey requires manage_api_key cluster privilege -func InvalidateAPIKey(ctx context.Context, client *Client, apikeyReq InvalidateAPIKeyRequest) (InvalidateAPIKeyResponse, error) { - var confirmation InvalidateAPIKeyResponse - req := esapi.SecurityInvalidateAPIKeyRequest{Body: esutil.NewJSONReader(apikeyReq)} - err := doRequest(ctx, client, req, &confirmation) - return confirmation, err -} - func HasPrivileges(ctx context.Context, client *Client, privileges HasPrivilegesRequest, credentials string) (HasPrivilegesResponse, error) { var info HasPrivilegesResponse req := esapi.SecurityHasPrivilegesRequest{Body: esutil.NewJSONReader(privileges)} @@ -66,27 +37,6 @@ func HasPrivileges(ctx context.Context, client *Client, privileges HasPrivileges return info, err } -type CreateAPIKeyRequest struct { - Name string `json:"name"` - Expiration *string `json:"expiration,omitempty"` - RoleDescriptors RoleDescriptor `json:"role_descriptors"` - Metadata map[string]interface{} `json:"metadata,omitempty"` -} - -type CreateAPIKeyResponse struct { - APIKey - Key string `json:"api_key"` -} - -type GetAPIKeyRequest struct { - APIKeyQuery - Owner bool `json:"owner"` -} - -type GetAPIKeyResponse struct { - APIKeys []APIKeyResponse `json:"api_keys"` -} - type HasPrivilegesRequest struct { // can't reuse the `Applications` type because here the JSON attribute must be singular Applications []Application `json:"application"` @@ -97,49 +47,12 @@ type HasPrivilegesResponse struct { Application map[AppName]PermissionsPerResource `json:"application"` } -type InvalidateAPIKeyRequest struct { - // normally the Elasticsearch API will require either Ids or Name, but not both - IDs []string `json:"ids,omitempty"` - Name *string `json:"name,omitempty"` -} - -type InvalidateAPIKeyResponse struct { - Invalidated []string `json:"invalidated_api_keys"` - ErrorCount int `json:"error_count"` -} - -type RoleDescriptor map[AppName]Applications - -type Applications struct { - Applications []Application `json:"applications"` -} - type Application struct { Name AppName `json:"application"` Privileges []PrivilegeAction `json:"privileges"` Resources []Resource `json:"resources"` } -type APIKeyResponse struct { - APIKey - Creation int64 `json:"creation"` - Invalidated bool `json:"invalidated"` - Username string `json:"username"` - Metadata map[string]interface{} `json:"metadata,omitempty"` -} - -type APIKeyQuery struct { - // normally the Elasticsearch API will require either Id or Name, but not both - ID *string `json:"id,omitempty"` - Name *string `json:"name,omitempty"` -} - -type APIKey struct { - ID string `json:"id"` - Name string `json:"name"` - ExpirationMs *int64 `json:"expiration,omitempty"` -} - type Permissions map[PrivilegeAction]bool type PermissionsPerResource map[Resource]Permissions diff --git a/internal/glog/go.mod b/internal/glog/go.mod deleted file mode 100644 index cff28a1260b..00000000000 --- a/internal/glog/go.mod +++ /dev/null @@ -1,3 +0,0 @@ -module github.com/golang/glog - -go 1.23.0 diff --git a/internal/glog/go.sum b/internal/glog/go.sum deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/internal/kibana/client.go b/internal/kibana/client.go index cf10c4a0d25..b4d8a4d7158 100644 --- a/internal/kibana/client.go +++ b/internal/kibana/client.go @@ -43,7 +43,7 @@ func NewClient(cfg ClientConfig) (*Client, error) { cfg.IgnoreVersion = true client, err := kibana.NewClientWithConfig( &cfg, "apm-server", - version.Version, + version.VersionWithQualifier(), version.CommitHash(), version.CommitTime().String(), ) diff --git a/internal/logs/selectors.go b/internal/logs/selectors.go index 8e17f74b575..2388eeb1468 100644 --- a/internal/logs/selectors.go +++ b/internal/logs/selectors.go @@ -24,7 +24,6 @@ const ( Handler = "handler" Ilm = "ilm" IndexManagement = "index-management" - Jaeger = "jaeger" Kibana = "kibana" Otel = "otel" Pipelines = "pipelines" diff --git a/internal/model/modelprocessor/eventcounter.go b/internal/model/modelprocessor/eventcounter.go index 6757fa57778..62bc21d7cb0 100644 --- a/internal/model/modelprocessor/eventcounter.go +++ b/internal/model/modelprocessor/eventcounter.go @@ -20,9 +20,8 @@ package modelprocessor import ( "context" "fmt" - "sync" - "github.com/elastic/elastic-agent-libs/monitoring" + "go.opentelemetry.io/otel/metric" "github.com/elastic/apm-data/model/modelpb" ) @@ -33,46 +32,30 @@ import ( // Metrics are named after the event type: `processor..transformations`. // These metrics are used to populate the "Processed Events" graphs in Stack Monitoring. type EventCounter struct { - registry *monitoring.Registry - - mu sync.RWMutex - eventCounters [modelpb.MaxEventType]*monitoring.Int + // Ideally event type would be a dimension, but we can't + // use dimensions when adapting to libbeat monitoring. + eventCounters [modelpb.MaxEventType + 1]metric.Int64Counter } // NewEventCounter returns an EventCounter that counts events processed, recording -// them as `.transformations` under the given registry. -func NewEventCounter(registry *monitoring.Registry) *EventCounter { - return &EventCounter{registry: registry} +// them as `apm-server.processor..transformations` under the given registry. +func NewEventCounter(mp metric.MeterProvider) *EventCounter { + meter := mp.Meter("github.com/elastic/apm-server/internal/model/modelprocessor") + c := &EventCounter{} + for i := range c.eventCounters { + eventType := modelpb.APMEventType(i) + counter, _ := meter.Int64Counter( + fmt.Sprintf("apm-server.processor.%s.transformations", eventType), + ) + c.eventCounters[i] = counter + } + return c } // ProcessBatch counts events in b, grouping by APMEvent.Processor.Event. func (c *EventCounter) ProcessBatch(ctx context.Context, b *modelpb.Batch) error { for _, event := range *b { - eventType := event.Type() - if eventType == modelpb.UndefinedEventType { - continue - } - - c.mu.RLock() - eventCounter := c.eventCounters[eventType-1] - c.mu.RUnlock() - if eventCounter == nil { - c.mu.Lock() - eventCounter = c.eventCounters[eventType-1] - if eventCounter == nil { - // Metric may exist in the registry but not in our map, - // so first check if it exists before attempting to create. - name := fmt.Sprintf("processor.%s.transformations", eventType) - var ok bool - eventCounter, ok = c.registry.Get(name).(*monitoring.Int) - if !ok { - eventCounter = monitoring.NewInt(c.registry, name) - } - c.eventCounters[eventType-1] = eventCounter - } - c.mu.Unlock() - } - eventCounter.Inc() + c.eventCounters[event.Type()].Add(ctx, 1) } return nil } diff --git a/internal/model/modelprocessor/eventcounter_test.go b/internal/model/modelprocessor/eventcounter_test.go index 3bf86fc1c82..7a38b68604c 100644 --- a/internal/model/modelprocessor/eventcounter_test.go +++ b/internal/model/modelprocessor/eventcounter_test.go @@ -22,10 +22,11 @@ import ( "testing" "github.com/stretchr/testify/assert" - - "github.com/elastic/elastic-agent-libs/monitoring" + sdkmetric "go.opentelemetry.io/otel/sdk/metric" + "go.opentelemetry.io/otel/sdk/metric/metricdata" "github.com/elastic/apm-data/model/modelpb" + "github.com/elastic/apm-server/internal/beater/monitoringtest" "github.com/elastic/apm-server/internal/model/modelprocessor" ) @@ -37,15 +38,19 @@ func TestEventCounter(t *testing.T) { {Transaction: &modelpb.Transaction{Type: "transaction_type"}}, } - expected := monitoring.MakeFlatSnapshot() - expected.Ints["processor.span.transformations"] = 1 - expected.Ints["processor.transaction.transformations"] = 2 + reader := sdkmetric.NewManualReader(sdkmetric.WithTemporalitySelector( + func(ik sdkmetric.InstrumentKind) metricdata.Temporality { + return metricdata.DeltaTemporality + }, + )) + mp := sdkmetric.NewMeterProvider(sdkmetric.WithReader(reader)) - registry := monitoring.NewRegistry() - processor := modelprocessor.NewEventCounter(registry) + processor := modelprocessor.NewEventCounter(mp) err := processor.ProcessBatch(context.Background(), &batch) assert.NoError(t, err) - snapshot := monitoring.CollectFlatSnapshot(registry, monitoring.Full, false) - assert.Equal(t, expected, snapshot) + monitoringtest.ExpectContainOtelMetrics(t, reader, map[string]any{ + "apm-server.processor.span.transformations": 1, + "apm-server.processor.transaction.transformations": 2, + }) } diff --git a/internal/processor/stream/result.go b/internal/processor/stream/result.go deleted file mode 100644 index 88bd5ea2868..00000000000 --- a/internal/processor/stream/result.go +++ /dev/null @@ -1,77 +0,0 @@ -// Licensed to Elasticsearch B.V. under one or more contributor -// license agreements. See the NOTICE file distributed with -// this work for additional information regarding copyright -// ownership. Elasticsearch B.V. licenses this file to you under -// the Apache License, Version 2.0 (the "License"); you may -// not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -package stream - -import ( - "errors" - - "github.com/elastic/elastic-agent-libs/monitoring" -) - -const ( - errorsLimit = 5 -) - -var ( - m = monitoring.Default.NewRegistry("apm-server.processor.stream") - mAccepted = monitoring.NewInt(m, "accepted") - mInvalid = monitoring.NewInt(m, "errors.invalid") - mTooLarge = monitoring.NewInt(m, "errors.toolarge") -) - -type Result struct { - Accepted int - Errors []error -} - -func (r *Result) LimitedAdd(err error) { - r.add(err, len(r.Errors) < errorsLimit) -} - -func (r *Result) Add(err error) { - r.add(err, true) -} - -func (r *Result) AddAccepted(ct int) { - r.Accepted += ct - mAccepted.Add(int64(ct)) -} - -func (r *Result) add(err error, add bool) { - var invalid *InvalidInputError - if errors.As(err, &invalid) { - if invalid.TooLarge { - mTooLarge.Inc() - } else { - mInvalid.Inc() - } - } - if add { - r.Errors = append(r.Errors, err) - } -} - -type InvalidInputError struct { - TooLarge bool - Message string - Document string -} - -func (e *InvalidInputError) Error() string { - return e.Message -} diff --git a/internal/processor/stream/result_test.go b/internal/processor/stream/result_test.go deleted file mode 100644 index b93718295b2..00000000000 --- a/internal/processor/stream/result_test.go +++ /dev/null @@ -1,68 +0,0 @@ -// Licensed to Elasticsearch B.V. under one or more contributor -// license agreements. See the NOTICE file distributed with -// this work for additional information regarding copyright -// ownership. Elasticsearch B.V. licenses this file to you under -// the Apache License, Version 2.0 (the "License"); you may -// not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -package stream - -import ( - "testing" - - "github.com/pkg/errors" - "github.com/stretchr/testify/assert" -) - -func TestResultAdd(t *testing.T) { - err1 := &InvalidInputError{Message: "err1", Document: "buf1"} - err2 := &InvalidInputError{Message: "err2", Document: "buf2"} - err3 := &InvalidInputError{Message: "err3", Document: "buf3"} - err4 := &InvalidInputError{Message: "err4"} - err5 := &InvalidInputError{Message: "err5"} - err6 := &InvalidInputError{Message: "err6"} - err7 := &InvalidInputError{Message: "err7"} - - result := Result{} - result.LimitedAdd(err1) - result.LimitedAdd(err2) - result.LimitedAdd(err3) - result.LimitedAdd(err4) - result.LimitedAdd(err5) - result.LimitedAdd(err5) - result.LimitedAdd(err6) // limited, not added - result.Add(err7) // unconditionally added - - assert.Len(t, result.Errors, 6) - assert.Equal(t, []error{err1, err2, err3, err4, err5, err7}, result.Errors) -} - -func TestMonitoring(t *testing.T) { - initialAccepted := mAccepted.Get() - initialInvalid := mInvalid.Get() - initialTooLarge := mTooLarge.Get() - - var result Result - result.AddAccepted(9) - result.AddAccepted(3) - for i := 0; i < 10; i++ { - result.LimitedAdd(&InvalidInputError{TooLarge: false}) - } - result.LimitedAdd(&InvalidInputError{TooLarge: true}) - result.Add(&InvalidInputError{TooLarge: true}) - result.Add(errors.New("error")) - - assert.Equal(t, int64(12), mAccepted.Get()-initialAccepted) - assert.Equal(t, int64(10), mInvalid.Get()-initialInvalid) - assert.Equal(t, int64(2), mTooLarge.Get()-initialTooLarge) -} diff --git a/internal/sourcemap/metadata_fetcher.go b/internal/sourcemap/metadata_fetcher.go index d375a501fda..7b00765f93b 100644 --- a/internal/sourcemap/metadata_fetcher.go +++ b/internal/sourcemap/metadata_fetcher.go @@ -159,6 +159,7 @@ func (s *MetadataESFetcher) sync(ctx context.Context) error { for { result, err = s.scrollsearch(ctx, scrollID, sourcemaps) if err != nil { + s.clearScroll(ctx, scrollID) if e := apm.CaptureError(ctx, err); e != nil { e.Send() } @@ -179,10 +180,28 @@ func (s *MetadataESFetcher) sync(ctx context.Context) error { } } + s.clearScroll(ctx, scrollID) + s.update(ctx, sourcemaps) return nil } +func (s *MetadataESFetcher) clearScroll(ctx context.Context, scrollID string) { + resp, err := esapi.ClearScrollRequest{ + ScrollID: []string{scrollID}, + }.Do(ctx, s.esClient) + if err != nil { + s.logger.Warnf("failed to clear scroll: %v", err) + return + } + + if resp.IsError() { + s.logger.Warnf("clearscroll request returned error: %s", resp.Status()) + } + + resp.Body.Close() +} + func (s *MetadataESFetcher) update(ctx context.Context, sourcemaps map[identifier]string) { span := apm.TransactionFromContext(ctx).StartSpan("MetadataESFetcher.update", "", nil) defer span.End() diff --git a/internal/sourcemap/metadata_fetcher_test.go b/internal/sourcemap/metadata_fetcher_test.go index 7c892890906..686711f7dc5 100644 --- a/internal/sourcemap/metadata_fetcher_test.go +++ b/internal/sourcemap/metadata_fetcher_test.go @@ -103,6 +103,12 @@ func TestMetadataFetcher(t *testing.T) { require.NotNil(t, tc.searchReponse, "nil searchReponse, possible unexpected request") // search request from the metadata fetcher tc.searchReponse(w, r) + case "/_search/scroll": + scrollIDValue := r.URL.Query().Get("scroll_id") + assert.Equal(t, scrollID, scrollIDValue) + w.Write([]byte(`{}`)) + case "/_search/scroll/" + scrollID: + assert.Equal(t, r.Method, http.MethodDelete) default: w.WriteHeader(http.StatusTeapot) t.Fatalf("unhandled request path: %s", r.URL.Path) @@ -234,6 +240,12 @@ func TestInvalidation(t *testing.T) { case "/.apm-source-map/_search": // search request from the metadata fetcher tc.searchReponse(w, r) + case "/_search/scroll": + scrollIDValue := r.URL.Query().Get("scroll_id") + assert.Equal(t, scrollID, scrollIDValue) + w.Write([]byte(`{}`)) + case "/_search/scroll/" + scrollID: + assert.Equal(t, r.Method, http.MethodDelete) default: w.WriteHeader(http.StatusTeapot) t.Fatalf("unhandled request path: %s", r.URL.Path) @@ -294,6 +306,8 @@ func TestInvalidation(t *testing.T) { } } +const scrollID = "FGluY2x1ZGVfY29udGV4dF91dWlkDXF1ZXJ5QW5kRmV0Y2gBFkJUT0Z5bFUtUXRXM3NTYno0dkM2MlEAAAAAAABnRBY5OUxYalAwUFFoS1NfLV9lWjlSYTRn" + func sourcemapSearchResponseBody(ids []metadata) []byte { m := make([]map[string]interface{}, 0, len(ids)) for _, id := range ids { @@ -318,6 +332,7 @@ func sourcemapSearchResponseBody(ids []metadata) []byte { }, "hits": m, }, + "_scroll_id": scrollID, } data, err := json.Marshal(result) diff --git a/internal/version/settings.go b/internal/version/settings.go index 1485abfa346..af6f4fae404 100644 --- a/internal/version/settings.go +++ b/internal/version/settings.go @@ -18,6 +18,7 @@ package version import ( + "fmt" "runtime/debug" "time" ) @@ -26,6 +27,7 @@ var ( vcsRevision string vcsTime time.Time vcsModified bool + qualifier string ) func init() { @@ -58,3 +60,11 @@ func CommitTime() time.Time { func VCSModified() bool { return vcsModified } + +// VersionWithQualifier returns the version and the qualifier. +func VersionWithQualifier() string { + if qualifier == "" { + return Version + } + return fmt.Sprintf("%s-%s", Version, qualifier) +} diff --git a/packaging.mk b/packaging.mk index aa61dd25f43..8a5052e9b81 100644 --- a/packaging.mk +++ b/packaging.mk @@ -27,9 +27,7 @@ DOCKER_BUILD_ARGS := \ DOCKER_IMAGES := \ build/docker/apm-server-$(APM_SERVER_VERSION).txt \ - build/docker/apm-server-$(APM_SERVER_VERSION)-SNAPSHOT.txt \ - build/docker/apm-server-ubi-$(APM_SERVER_VERSION).txt \ - build/docker/apm-server-ubi-$(APM_SERVER_VERSION)-SNAPSHOT.txt + build/docker/apm-server-$(APM_SERVER_VERSION)-SNAPSHOT.txt # If GENERATE_WOLFI_IMAGES is set then generate wolfi docker images. ifdef GENERATE_WOLFI_IMAGES @@ -42,7 +40,6 @@ build/docker/%.txt: DOCKER_IMAGE_TAG := docker.elastic.co/apm/apm-server:% build/docker/%.txt: VERSION := $(APM_SERVER_VERSION) build/docker/%.txt: DOCKER_FILE_ARGS := -f packaging/docker/Dockerfile build/docker/%-SNAPSHOT.txt: VERSION := $(APM_SERVER_VERSION)-SNAPSHOT -build/docker/apm-server-ubi-%.txt: DOCKER_BUILD_ARGS+=--build-arg BASE_IMAGE=docker.elastic.co/ubi9/ubi-minimal build/docker/apm-server-wolfi-%.txt: DOCKER_FILE_ARGS := -f packaging/docker/Dockerfile.wolfi INTERNAL_DOCKER_IMAGE := docker.elastic.co/observability-ci/apm-server-internal @@ -59,7 +56,7 @@ $(DOCKER_IMAGES): # Docker image tarballs. We distribute UBI Docker images only for AMD64. DOCKER_IMAGE_SUFFIX := docker-image$(if $(findstring arm64,$(GOARCH)),-arm64).tar.gz -DOCKER_IMAGE_PREFIXES := apm-server $(if $(findstring amd64,$(GOARCH)), apm-server-ubi) +DOCKER_IMAGE_PREFIXES := apm-server # If GENERATE_WOLFI_IMAGES is set then generate wolfi docker images. ifdef GENERATE_WOLFI_IMAGES DOCKER_IMAGE_PREFIXES := $(DOCKER_IMAGE_PREFIXES) apm-server-wolfi diff --git a/packaging/docker/Dockerfile b/packaging/docker/Dockerfile index 22b6c48db74..4d894daeb4f 100644 --- a/packaging/docker/Dockerfile +++ b/packaging/docker/Dockerfile @@ -1,4 +1,3 @@ -ARG BASE_IMAGE=ubuntu:22.04 ARG GOLANG_VERSION ################################################################################ @@ -6,10 +5,9 @@ ARG GOLANG_VERSION # Build the apm-server binary. The golang image version is kept # up to date with go.mod by Makefile. ################################################################################ -FROM golang:${GOLANG_VERSION} as builder +FROM golang:${GOLANG_VERSION} AS builder WORKDIR /src COPY go.mod go.sum .go-version /src/ -COPY internal/glog/go.mod /src/internal/glog/go.mod RUN --mount=type=cache,target=/go/pkg/mod go mod download COPY Makefile *.mk /src/ COPY cmd /src/cmd @@ -22,19 +20,21 @@ RUN --mount=type=cache,target=/go/pkg/mod \ --mount=type=cache,target=/root/.cache/go-build \ make apm-server +COPY apm-server.yml ./apm-server.yml +COPY --chmod=0644 apm-server.yml ./apm-server.yml +RUN sed -i 's/127.0.0.1:8200/0.0.0.0:8200/' apm-server.yml +RUN sed -i 's/localhost:9200/elasticsearch:9200/' apm-server.yml + ################################################################################ # Build stage 1 # Copy prepared files from the previous stage and complete the image. ################################################################################ -FROM ${BASE_IMAGE} +FROM registry.access.redhat.com/ubi9/ubi-micro:latest@sha256:f6e0a71b7e0875b54ea559c2e0a6478703268a8d4b8bdcf5d911d0dae76aef51 ARG TARGETARCH ARG BUILD_DATE ARG VERSION ARG VCS_REF -# Add an init process. -ADD --chmod=0755 packaging/docker/tini-${TARGETARCH}.tar.xz /usr/bin - # Statically defined labels. LABEL \ org.label-schema.schema-version="1.0" \ @@ -65,8 +65,7 @@ LABEL \ org.opencontainers.image.created=${BUILD_DATE} \ version=${VERSION} -ENV ELASTIC_CONTAINER "true" -ENV PATH=/usr/share/apm-server:$PATH +ENV ELASTIC_CONTAINER="true" # When running under Docker, we must ensure libbeat monitoring pulls cgroup # metrics from /sys/fs/cgroup//, ignoring any paths found in @@ -77,21 +76,16 @@ ENV LIBBEAT_MONITORING_CGROUPS_HIERARCHY_OVERRIDE=/ # running in Docker. ENV BEAT_STRICT_PERMS=false -COPY --chmod=0755 packaging/docker/docker-entrypoint /usr/local/bin/docker-entrypoint COPY --chmod=0644 licenses/ELASTIC-LICENSE-2.0.txt NOTICE.txt /licenses/ -COPY --chmod=0644 packaging/docker/cacert.pem /etc/pki/tls/certs/ca-bundle.crt -# Copy files world-readable, and create the data directory world-writeable, -# to permit running the container with arbitrary UIDs and GIDs. WORKDIR /usr/share/apm-server -COPY --chmod=0644 apm-server.yml ./apm-server.yml -COPY --chmod=0755 --from=builder /src/apm-server ./apm-server -RUN sed -i 's/127.0.0.1:8200/0.0.0.0:8200/' apm-server.yml -RUN sed -i 's/localhost:9200/elasticsearch:9200/' apm-server.yml -RUN mkdir --mode=0777 data + RUN echo 'apm-server:*:1000:1000::/usr/share/apm-server:/bin/false' >> /etc/passwd RUN chown -R 1000:1000 /usr/share/apm-server +COPY --chmod=0755 --chown=1000:1000 --from=builder /src/apm-server ./apm-server +COPY --chmod=0644 --chown=1000:1000 --from=builder /src/apm-server.yml ./apm-server.yml + USER apm-server EXPOSE 8200 -ENTRYPOINT ["/usr/bin/tini", "--", "/usr/local/bin/docker-entrypoint"] +ENTRYPOINT ["/usr/share/apm-server/apm-server", "--environment=container"] diff --git a/packaging/docker/Dockerfile.wolfi b/packaging/docker/Dockerfile.wolfi index b4990957aec..a58e67e98d6 100644 --- a/packaging/docker/Dockerfile.wolfi +++ b/packaging/docker/Dockerfile.wolfi @@ -8,7 +8,6 @@ ARG GOLANG_VERSION FROM docker.elastic.co/wolfi/go:${GOLANG_VERSION} as builder WORKDIR /src COPY go.mod go.sum .go-version /src/ -COPY internal/glog/go.mod /src/internal/glog/go.mod RUN --mount=type=cache,target=/go/pkg/mod go mod download COPY Makefile *.mk /src/ COPY cmd /src/cmd @@ -30,7 +29,7 @@ RUN sed -i 's/localhost:9200/elasticsearch:9200/' apm-server.yml # Build stage 1 # Copy prepared files from the previous stage and complete the image. ################################################################################ -FROM cgr.dev/chainguard/static:latest@sha256:f0444e0c32aa0d22cca6de79e160306e9f24140fea0ac97c41789ee59814aa87 +FROM cgr.dev/chainguard/static:latest@sha256:853bfd4495abb4b65ede8fc9332513ca2626235589c2cef59b4fce5082d0836d ARG TARGETARCH ARG BUILD_DATE ARG VERSION diff --git a/packaging/docker/cacert.pem b/packaging/docker/cacert.pem deleted file mode 100644 index 6b93dc34f8c..00000000000 --- a/packaging/docker/cacert.pem +++ /dev/null @@ -1,3363 +0,0 @@ -## -## Bundle of CA Root Certificates -## -## Certificate data from Mozilla as of: Tue May 30 03:12:04 2023 GMT -## -## This is a bundle of X.509 certificates of public Certificate Authorities -## (CA). These were automatically extracted from Mozilla's root certificates -## file (certdata.txt). This file can be found in the mozilla source tree: -## https://hg.mozilla.org/releases/mozilla-release/raw-file/default/security/nss/lib/ckfw/builtins/certdata.txt -## -## It contains the certificates in PEM format and therefore -## can be directly used with curl / libcurl / php_curl, or with -## an Apache+mod_ssl webserver for SSL client authentication. -## Just configure this file as the SSLCACertificateFile. -## -## Conversion done with mk-ca-bundle.pl version 1.29. -## SHA256: c47475103fb05bb562bbadff0d1e72346b03236154e1448a6ca191b740f83507 -## - - -GlobalSign Root CA -================== ------BEGIN CERTIFICATE----- -MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkGA1UEBhMCQkUx -GTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jvb3QgQ0ExGzAZBgNVBAMTEkds -b2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAwMDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNV -BAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYD -VQQDExJHbG9iYWxTaWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDa -DuaZjc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavpxy0Sy6sc -THAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp1Wrjsok6Vjk4bwY8iGlb -Kk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdGsnUOhugZitVtbNV4FpWi6cgKOOvyJBNP -c1STE4U6G7weNLWLBYy5d4ux2x8gkasJU26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrX -gzT/LCrBbBlDSgeF59N89iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV -HRMBAf8EBTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0BAQUF -AAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOzyj1hTdNGCbM+w6Dj -Y1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE38NflNUVyRRBnMRddWQVDf9VMOyG -j/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymPAbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhH -hm4qxFYxldBniYUr+WymXUadDKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveC -X4XSQRjbgbMEHMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A== ------END CERTIFICATE----- - -Entrust.net Premium 2048 Secure Server CA -========================================= ------BEGIN CERTIFICATE----- -MIIEKjCCAxKgAwIBAgIEOGPe+DANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChMLRW50cnVzdC5u -ZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBpbmNvcnAuIGJ5IHJlZi4gKGxp -bWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNV -BAMTKkVudHJ1c3QubmV0IENlcnRpZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw05OTEyMjQx -NzUwNTFaFw0yOTA3MjQxNDE1MTJaMIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3 -d3d3LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTEl -MCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEGA1UEAxMqRW50cnVzdC5u -ZXQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgpMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A -MIIBCgKCAQEArU1LqRKGsuqjIAcVFmQqK0vRvwtKTY7tgHalZ7d4QMBzQshowNtTK91euHaYNZOL -Gp18EzoOH1u3Hs/lJBQesYGpjX24zGtLA/ECDNyrpUAkAH90lKGdCCmziAv1h3edVc3kw37XamSr -hRSGlVuXMlBvPci6Zgzj/L24ScF2iUkZ/cCovYmjZy/Gn7xxGWC4LeksyZB2ZnuU4q941mVTXTzW -nLLPKQP5L6RQstRIzgUyVYr9smRMDuSYB3Xbf9+5CFVghTAp+XtIpGmG4zU/HoZdenoVve8AjhUi -VBcAkCaTvA5JaJG/+EfTnZVCwQ5N328mz8MYIWJmQ3DW1cAH4QIDAQABo0IwQDAOBgNVHQ8BAf8E -BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUVeSB0RGAvtiJuQijMfmhJAkWuXAwDQYJ -KoZIhvcNAQEFBQADggEBADubj1abMOdTmXx6eadNl9cZlZD7Bh/KM3xGY4+WZiT6QBshJ8rmcnPy -T/4xmf3IDExoU8aAghOY+rat2l098c5u9hURlIIM7j+VrxGrD9cv3h8Dj1csHsm7mhpElesYT6Yf -zX1XEC+bBAlahLVu2B064dae0Wx5XnkcFMXj0EyTO2U87d89vqbllRrDtRnDvV5bu/8j72gZyxKT -J1wDLW8w0B62GqzeWvfRqqgnpv55gcR5mTNXuhKwqeBCbJPKVt7+bYQLCIt+jerXmCHG8+c8eS9e -nNFMFY3h7CI3zJpDC5fcgJCNs2ebb0gIFVbPv/ErfF6adulZkMV8gzURZVE= ------END CERTIFICATE----- - -Baltimore CyberTrust Root -========================= ------BEGIN CERTIFICATE----- -MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJRTESMBAGA1UE -ChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYDVQQDExlCYWx0aW1vcmUgQ3li -ZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoXDTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMC -SUUxEjAQBgNVBAoTCUJhbHRpbW9yZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFs -dGltb3JlIEN5YmVyVHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKME -uyKrmD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjrIZ3AQSsB -UnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeKmpYcqWe4PwzV9/lSEy/C -G9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSuXmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9 -XbIGevOF6uvUA65ehD5f/xXtabz5OTZydc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjpr -l3RjM71oGDHweI12v/yejl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoI -VDaGezq1BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEB -BQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT929hkTI7gQCvlYpNRh -cL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3WgxjkzSswF07r51XgdIGn9w/xZchMB5 -hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsa -Y71k5h+3zvDyny67G7fyUIhzksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9H -RCwBXbsdtTLSR9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp ------END CERTIFICATE----- - -Entrust Root Certification Authority -==================================== ------BEGIN CERTIFICATE----- -MIIEkTCCA3mgAwIBAgIERWtQVDANBgkqhkiG9w0BAQUFADCBsDELMAkGA1UEBhMCVVMxFjAUBgNV -BAoTDUVudHJ1c3QsIEluYy4xOTA3BgNVBAsTMHd3dy5lbnRydXN0Lm5ldC9DUFMgaXMgaW5jb3Jw -b3JhdGVkIGJ5IHJlZmVyZW5jZTEfMB0GA1UECxMWKGMpIDIwMDYgRW50cnVzdCwgSW5jLjEtMCsG -A1UEAxMkRW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA2MTEyNzIwMjM0 -MloXDTI2MTEyNzIwNTM0MlowgbAxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMu -MTkwNwYDVQQLEzB3d3cuZW50cnVzdC5uZXQvQ1BTIGlzIGluY29ycG9yYXRlZCBieSByZWZlcmVu -Y2UxHzAdBgNVBAsTFihjKSAyMDA2IEVudHJ1c3QsIEluYy4xLTArBgNVBAMTJEVudHJ1c3QgUm9v -dCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB -ALaVtkNC+sZtKm9I35RMOVcF7sN5EUFoNu3s/poBj6E4KPz3EEZmLk0eGrEaTsbRwJWIsMn/MYsz -A9u3g3s+IIRe7bJWKKf44LlAcTfFy0cOlypowCKVYhXbR9n10Cv/gkvJrT7eTNuQgFA/CYqEAOww -Cj0Yzfv9KlmaI5UXLEWeH25DeW0MXJj+SKfFI0dcXv1u5x609mhF0YaDW6KKjbHjKYD+JXGIrb68 -j6xSlkuqUY3kEzEZ6E5Nn9uss2rVvDlUccp6en+Q3X0dgNmBu1kmwhH+5pPi94DkZfs0Nw4pgHBN -rziGLp5/V6+eF67rHMsoIV+2HNjnogQi+dPa2MsCAwEAAaOBsDCBrTAOBgNVHQ8BAf8EBAMCAQYw -DwYDVR0TAQH/BAUwAwEB/zArBgNVHRAEJDAigA8yMDA2MTEyNzIwMjM0MlqBDzIwMjYxMTI3MjA1 -MzQyWjAfBgNVHSMEGDAWgBRokORnpKZTgMeGZqTx90tD+4S9bTAdBgNVHQ4EFgQUaJDkZ6SmU4DH -hmak8fdLQ/uEvW0wHQYJKoZIhvZ9B0EABBAwDhsIVjcuMTo0LjADAgSQMA0GCSqGSIb3DQEBBQUA -A4IBAQCT1DCw1wMgKtD5Y+iRDAUgqV8ZyntyTtSx29CW+1RaGSwMCPeyvIWonX9tO1KzKtvn1ISM -Y/YPyyYBkVBs9F8U4pN0wBOeMDpQ47RgxRzwIkSNcUesyBrJ6ZuaAGAT/3B+XxFNSRuzFVJ7yVTa -v52Vr2ua2J7p8eRDjeIRRDq/r72DQnNSi6q7pynP9WQcCk3RvKqsnyrQ/39/2n3qse0wJcGE2jTS -W3iDVuycNsMm4hH2Z0kdkquM++v/eu6FSqdQgPCnXEqULl8FmTxSQeDNtGPPAUO6nIPcj2A781q0 -tHuu2guQOHXvgR1m0vdXcDazv/wor3ElhVsT/h5/WrQ8 ------END CERTIFICATE----- - -Comodo AAA Services root -======================== ------BEGIN CERTIFICATE----- -MIIEMjCCAxqgAwIBAgIBATANBgkqhkiG9w0BAQUFADB7MQswCQYDVQQGEwJHQjEbMBkGA1UECAwS -R3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRowGAYDVQQKDBFDb21vZG8gQ0Eg -TGltaXRlZDEhMB8GA1UEAwwYQUFBIENlcnRpZmljYXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAw -MFoXDTI4MTIzMTIzNTk1OVowezELMAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hl -c3RlcjEQMA4GA1UEBwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNV -BAMMGEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC -ggEBAL5AnfRu4ep2hxxNRUSOvkbIgwadwSr+GB+O5AL686tdUIoWMQuaBtDFcCLNSS1UY8y2bmhG -C1Pqy0wkwLxyTurxFa70VJoSCsN6sjNg4tqJVfMiWPPe3M/vg4aijJRPn2jymJBGhCfHdr/jzDUs -i14HZGWCwEiwqJH5YZ92IFCokcdmtet4YgNW8IoaE+oxox6gmf049vYnMlhvB/VruPsUK6+3qszW -Y19zjNoFmag4qMsXeDZRrOme9Hg6jc8P2ULimAyrL58OAd7vn5lJ8S3frHRNG5i1R8XlKdH5kBjH -Ypy+g8cmez6KJcfA3Z3mNWgQIJ2P2N7Sw4ScDV7oL8kCAwEAAaOBwDCBvTAdBgNVHQ4EFgQUoBEK -Iz6W8Qfs4q8p74Klf9AwpLQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wewYDVR0f -BHQwcjA4oDagNIYyaHR0cDovL2NybC5jb21vZG9jYS5jb20vQUFBQ2VydGlmaWNhdGVTZXJ2aWNl -cy5jcmwwNqA0oDKGMGh0dHA6Ly9jcmwuY29tb2RvLm5ldC9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2Vz -LmNybDANBgkqhkiG9w0BAQUFAAOCAQEACFb8AvCb6P+k+tZ7xkSAzk/ExfYAWMymtrwUSWgEdujm -7l3sAg9g1o1QGE8mTgHj5rCl7r+8dFRBv/38ErjHT1r0iWAFf2C3BUrz9vHCv8S5dIa2LX1rzNLz -Rt0vxuBqw8M0Ayx9lt1awg6nCpnBBYurDC/zXDrPbDdVCYfeU0BsWO/8tqtlbgT2G9w84FoVxp7Z -8VlIMCFlA2zs6SFz7JsDoeA3raAVGI/6ugLOpyypEBMs1OUIJqsil2D4kF501KKaU73yqWjgom7C -12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3tPxq3smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg== ------END CERTIFICATE----- - -QuoVadis Root CA 2 -================== ------BEGIN CERTIFICATE----- -MIIFtzCCA5+gAwIBAgICBQkwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0xGTAXBgNVBAoT -EFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJvb3QgQ0EgMjAeFw0wNjExMjQx -ODI3MDBaFw0zMTExMjQxODIzMzNaMEUxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM -aW1pdGVkMRswGQYDVQQDExJRdW9WYWRpcyBSb290IENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4IC -DwAwggIKAoICAQCaGMpLlA0ALa8DKYrwD4HIrkwZhR0In6spRIXzL4GtMh6QRr+jhiYaHv5+HBg6 -XJxgFyo6dIMzMH1hVBHL7avg5tKifvVrbxi3Cgst/ek+7wrGsxDp3MJGF/hd/aTa/55JWpzmM+Yk -lvc/ulsrHHo1wtZn/qtmUIttKGAr79dgw8eTvI02kfN/+NsRE8Scd3bBrrcCaoF6qUWD4gXmuVbB -lDePSHFjIuwXZQeVikvfj8ZaCuWw419eaxGrDPmF60Tp+ARz8un+XJiM9XOva7R+zdRcAitMOeGy -lZUtQofX1bOQQ7dsE/He3fbE+Ik/0XX1ksOR1YqI0JDs3G3eicJlcZaLDQP9nL9bFqyS2+r+eXyt -66/3FsvbzSUr5R/7mp/iUcw6UwxI5g69ybR2BlLmEROFcmMDBOAENisgGQLodKcftslWZvB1Jdxn -wQ5hYIizPtGo/KPaHbDRsSNU30R2be1B2MGyIrZTHN81Hdyhdyox5C315eXbyOD/5YDXC2Og/zOh -D7osFRXql7PSorW+8oyWHhqPHWykYTe5hnMz15eWniN9gqRMgeKh0bpnX5UHoycR7hYQe7xFSkyy -BNKr79X9DFHOUGoIMfmR2gyPZFwDwzqLID9ujWc9Otb+fVuIyV77zGHcizN300QyNQliBJIWENie -J0f7OyHj+OsdWwIDAQABo4GwMIGtMA8GA1UdEwEB/wQFMAMBAf8wCwYDVR0PBAQDAgEGMB0GA1Ud -DgQWBBQahGK8SEwzJQTU7tD2A8QZRtGUazBuBgNVHSMEZzBlgBQahGK8SEwzJQTU7tD2A8QZRtGU -a6FJpEcwRTELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMT -ElF1b1ZhZGlzIFJvb3QgQ0EgMoICBQkwDQYJKoZIhvcNAQEFBQADggIBAD4KFk2fBluornFdLwUv -Z+YTRYPENvbzwCYMDbVHZF34tHLJRqUDGCdViXh9duqWNIAXINzng/iN/Ae42l9NLmeyhP3ZRPx3 -UIHmfLTJDQtyU/h2BwdBR5YM++CCJpNVjP4iH2BlfF/nJrP3MpCYUNQ3cVX2kiF495V5+vgtJodm -VjB3pjd4M1IQWK4/YY7yarHvGH5KWWPKjaJW1acvvFYfzznB4vsKqBUsfU16Y8Zsl0Q80m/DShcK -+JDSV6IZUaUtl0HaB0+pUNqQjZRG4T7wlP0QADj1O+hA4bRuVhogzG9Yje0uRY/W6ZM/57Es3zrW -IozchLsib9D45MY56QSIPMO661V6bYCZJPVsAfv4l7CUW+v90m/xd2gNNWQjrLhVoQPRTUIZ3Ph1 -WVaj+ahJefivDrkRoHy3au000LYmYjgahwz46P0u05B/B5EqHdZ+XIWDmbA4CD/pXvk1B+TJYm5X -f6dQlfe6yJvmjqIBxdZmv3lh8zwc4bmCXF2gw+nYSL0ZohEUGW6yhhtoPkg3Goi3XZZenMfvJ2II -4pEZXNLxId26F0KCl3GBUzGpn/Z9Yr9y4aOTHcyKJloJONDO1w2AFrR4pTqHTI2KpdVGl/IsELm8 -VCLAAVBpQ570su9t+Oza8eOx79+Rj1QqCyXBJhnEUhAFZdWCEOrCMc0u ------END CERTIFICATE----- - -QuoVadis Root CA 3 -================== ------BEGIN CERTIFICATE----- -MIIGnTCCBIWgAwIBAgICBcYwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0xGTAXBgNVBAoT -EFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJvb3QgQ0EgMzAeFw0wNjExMjQx -OTExMjNaFw0zMTExMjQxOTA2NDRaMEUxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM -aW1pdGVkMRswGQYDVQQDExJRdW9WYWRpcyBSb290IENBIDMwggIiMA0GCSqGSIb3DQEBAQUAA4IC -DwAwggIKAoICAQDMV0IWVJzmmNPTTe7+7cefQzlKZbPoFog02w1ZkXTPkrgEQK0CSzGrvI2RaNgg -DhoB4hp7Thdd4oq3P5kazethq8Jlph+3t723j/z9cI8LoGe+AaJZz3HmDyl2/7FWeUUrH556VOij -KTVopAFPD6QuN+8bv+OPEKhyq1hX51SGyMnzW9os2l2ObjyjPtr7guXd8lyyBTNvijbO0BNO/79K -DDRMpsMhvVAEVeuxu537RR5kFd5VAYwCdrXLoT9CabwvvWhDFlaJKjdhkf2mrk7AyxRllDdLkgbv -BNDInIjbC3uBr7E9KsRlOni27tyAsdLTmZw67mtaa7ONt9XOnMK+pUsvFrGeaDsGb659n/je7Mwp -p5ijJUMv7/FfJuGITfhebtfZFG4ZM2mnO4SJk8RTVROhUXhA+LjJou57ulJCg54U7QVSWllWp5f8 -nT8KKdjcT5EOE7zelaTfi5m+rJsziO+1ga8bxiJTyPbH7pcUsMV8eFLI8M5ud2CEpukqdiDtWAEX -MJPpGovgc2PZapKUSU60rUqFxKMiMPwJ7Wgic6aIDFUhWMXhOp8q3crhkODZc6tsgLjoC2SToJyM -Gf+z0gzskSaHirOi4XCPLArlzW1oUevaPwV/izLmE1xr/l9A4iLItLRkT9a6fUg+qGkM17uGcclz -uD87nSVL2v9A6wIDAQABo4IBlTCCAZEwDwYDVR0TAQH/BAUwAwEB/zCB4QYDVR0gBIHZMIHWMIHT -BgkrBgEEAb5YAAMwgcUwgZMGCCsGAQUFBwICMIGGGoGDQW55IHVzZSBvZiB0aGlzIENlcnRpZmlj -YXRlIGNvbnN0aXR1dGVzIGFjY2VwdGFuY2Ugb2YgdGhlIFF1b1ZhZGlzIFJvb3QgQ0EgMyBDZXJ0 -aWZpY2F0ZSBQb2xpY3kgLyBDZXJ0aWZpY2F0aW9uIFByYWN0aWNlIFN0YXRlbWVudC4wLQYIKwYB -BQUHAgEWIWh0dHA6Ly93d3cucXVvdmFkaXNnbG9iYWwuY29tL2NwczALBgNVHQ8EBAMCAQYwHQYD -VR0OBBYEFPLAE+CCQz777i9nMpY1XNu4ywLQMG4GA1UdIwRnMGWAFPLAE+CCQz777i9nMpY1XNu4 -ywLQoUmkRzBFMQswCQYDVQQGEwJCTTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDEbMBkGA1UE -AxMSUXVvVmFkaXMgUm9vdCBDQSAzggIFxjANBgkqhkiG9w0BAQUFAAOCAgEAT62gLEz6wPJv92ZV -qyM07ucp2sNbtrCD2dDQ4iH782CnO11gUyeim/YIIirnv6By5ZwkajGxkHon24QRiSemd1o417+s -hvzuXYO8BsbRd2sPbSQvS3pspweWyuOEn62Iix2rFo1bZhfZFvSLgNLd+LJ2w/w4E6oM3kJpK27z -POuAJ9v1pkQNn1pVWQvVDVJIxa6f8i+AxeoyUDUSly7B4f/xI4hROJ/yZlZ25w9Rl6VSDE1JUZU2 -Pb+iSwwQHYaZTKrzchGT5Or2m9qoXadNt54CrnMAyNojA+j56hl0YgCUyyIgvpSnWbWCar6ZeXqp -8kokUvd0/bpO5qgdAm6xDYBEwa7TIzdfu4V8K5Iu6H6li92Z4b8nby1dqnuH/grdS/yO9SbkbnBC -bjPsMZ57k8HkyWkaPcBrTiJt7qtYTcbQQcEr6k8Sh17rRdhs9ZgC06DYVYoGmRmioHfRMJ6szHXu -g/WwYjnPbFfiTNKRCw51KBuav/0aQ/HKd/s7j2G4aSgWQgRecCocIdiP4b0jWy10QJLZYxkNc91p -vGJHvOB0K7Lrfb5BG7XARsWhIstfTsEokt4YutUqKLsRixeTmJlglFwjz1onl14LBQaTNx47aTbr -qZ5hHY8y2o4M1nQ+ewkk2gF3R8Q7zTSMmfXK4SVhM7JZG+Ju1zdXtg2pEto= ------END CERTIFICATE----- - -Security Communication Root CA -============================== ------BEGIN CERTIFICATE----- -MIIDWjCCAkKgAwIBAgIBADANBgkqhkiG9w0BAQUFADBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMP -U0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEw -HhcNMDMwOTMwMDQyMDQ5WhcNMjMwOTMwMDQyMDQ5WjBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMP -U0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEw -ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCzs/5/022x7xZ8V6UMbXaKL0u/ZPtM7orw -8yl89f/uKuDp6bpbZCKamm8sOiZpUQWZJtzVHGpxxpp9Hp3dfGzGjGdnSj74cbAZJ6kJDKaVv0uM -DPpVmDvY6CKhS3E4eayXkmmziX7qIWgGmBSWh9JhNrxtJ1aeV+7AwFb9Ms+k2Y7CI9eNqPPYJayX -5HA49LY6tJ07lyZDo6G8SVlyTCMwhwFY9k6+HGhWZq/NQV3Is00qVUarH9oe4kA92819uZKAnDfd -DJZkndwi92SL32HeFZRSFaB9UslLqCHJxrHty8OVYNEP8Ktw+N/LTX7s1vqr2b1/VPKl6Xn62dZ2 -JChzAgMBAAGjPzA9MB0GA1UdDgQWBBSgc0mZaNyFW2XjmygvV5+9M7wHSDALBgNVHQ8EBAMCAQYw -DwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAaECpqLvkT115swW1F7NgE+vGkl3g -0dNq/vu+m22/xwVtWSDEHPC32oRYAmP6SBbvT6UL90qY8j+eG61Ha2POCEfrUj94nK9NrvjVT8+a -mCoQQTlSxN3Zmw7vkwGusi7KaEIkQmywszo+zenaSMQVy+n5Bw+SUEmK3TGXX8npN6o7WWWXlDLJ -s58+OmJYxUmtYg5xpTKqL8aJdkNAExNnPaJUJRDL8Try2frbSVa7pv6nQTXD4IhhyYjH3zYQIphZ -6rBK+1YWc26sTfcioU+tHXotRSflMMFe8toTyyVCUZVHA4xsIcx0Qu1T/zOLjw9XARYvz6buyXAi -FL39vmwLAw== ------END CERTIFICATE----- - -XRamp Global CA Root -==================== ------BEGIN CERTIFICATE----- -MIIEMDCCAxigAwIBAgIQUJRs7Bjq1ZxN1ZfvdY+grTANBgkqhkiG9w0BAQUFADCBgjELMAkGA1UE -BhMCVVMxHjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2Vj -dXJpdHkgU2VydmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBB -dXRob3JpdHkwHhcNMDQxMTAxMTcxNDA0WhcNMzUwMTAxMDUzNzE5WjCBgjELMAkGA1UEBhMCVVMx -HjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2VjdXJpdHkg -U2VydmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBBdXRob3Jp -dHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCYJB69FbS638eMpSe2OAtp87ZOqCwu -IR1cRN8hXX4jdP5efrRKt6atH67gBhbim1vZZ3RrXYCPKZ2GG9mcDZhtdhAoWORlsH9KmHmf4MMx -foArtYzAQDsRhtDLooY2YKTVMIJt2W7QDxIEM5dfT2Fa8OT5kavnHTu86M/0ay00fOJIYRyO82FE -zG+gSqmUsE3a56k0enI4qEHMPJQRfevIpoy3hsvKMzvZPTeL+3o+hiznc9cKV6xkmxnr9A8ECIqs -AxcZZPRaJSKNNCyy9mgdEm3Tih4U2sSPpuIjhdV6Db1q4Ons7Be7QhtnqiXtRYMh/MHJfNViPvry -xS3T/dRlAgMBAAGjgZ8wgZwwEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1Ud -EwEB/wQFMAMBAf8wHQYDVR0OBBYEFMZPoj0GY4QJnM5i5ASsjVy16bYbMDYGA1UdHwQvMC0wK6Ap -oCeGJWh0dHA6Ly9jcmwueHJhbXBzZWN1cml0eS5jb20vWEdDQS5jcmwwEAYJKwYBBAGCNxUBBAMC -AQEwDQYJKoZIhvcNAQEFBQADggEBAJEVOQMBG2f7Shz5CmBbodpNl2L5JFMn14JkTpAuw0kbK5rc -/Kh4ZzXxHfARvbdI4xD2Dd8/0sm2qlWkSLoC295ZLhVbO50WfUfXN+pfTXYSNrsf16GBBEYgoyxt -qZ4Bfj8pzgCT3/3JknOJiWSe5yvkHJEs0rnOfc5vMZnT5r7SHpDwCRR5XCOrTdLaIR9NmXmd4c8n -nxCbHIgNsIpkQTG4DmyQJKSbXHGPurt+HBvbaoAPIbzp26a3QPSyi6mx5O+aGtA9aZnuqCij4Tyz -8LIRnM98QObd50N9otg6tamN8jSZxNQQ4Qb9CYQQO+7ETPTsJ3xCwnR8gooJybQDJbw= ------END CERTIFICATE----- - -Go Daddy Class 2 CA -=================== ------BEGIN CERTIFICATE----- -MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMY -VGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRp -ZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3MDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkG -A1UEBhMCVVMxITAfBgNVBAoTGFRoZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28g -RGFkZHkgQ2xhc3MgMiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQAD -ggENADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCAPVYYYwhv -2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6wwdhFJ2+qN1j3hybX2C32 -qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXiEqITLdiOr18SPaAIBQi2XKVlOARFmR6j -YGB0xUGlcmIbYsUfb18aQr4CUWWoriMYavx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmY -vLEHZ6IVDd2gWMZEewo+YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0O -BBYEFNLEsNKR1EwRcbNhyz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h/t2o -atTjoWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMu -MTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggEAMAwG -A1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wim -PQoZ+YeAEW5p5JYXMP80kWNyOO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKt -I3lpjbi2Tc7PTMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ -HmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mERdEr/VxqHD3VI -Ls9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5CufReYNnyicsbkqWletNw+vHX/b -vZ8= ------END CERTIFICATE----- - -Starfield Class 2 CA -==================== ------BEGIN CERTIFICATE----- -MIIEDzCCAvegAwIBAgIBADANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJVUzElMCMGA1UEChMc -U3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMpU3RhcmZpZWxkIENsYXNzIDIg -Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQwNjI5MTczOTE2WhcNMzQwNjI5MTczOTE2WjBo -MQswCQYDVQQGEwJVUzElMCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAG -A1UECxMpU3RhcmZpZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEgMA0GCSqG -SIb3DQEBAQUAA4IBDQAwggEIAoIBAQC3Msj+6XGmBIWtDBFk385N78gDGIc/oav7PKaf8MOh2tTY -bitTkPskpD6E8J7oX+zlJ0T1KKY/e97gKvDIr1MvnsoFAZMej2YcOadN+lq2cwQlZut3f+dZxkqZ -JRRU6ybH838Z1TBwj6+wRir/resp7defqgSHo9T5iaU0X9tDkYI22WY8sbi5gv2cOj4QyDvvBmVm -epsZGD3/cVE8MC5fvj13c7JdBmzDI1aaK4UmkhynArPkPw2vCHmCuDY96pzTNbO8acr1zJ3o/WSN -F4Azbl5KXZnJHoe0nRrA1W4TNSNe35tfPe/W93bC6j67eA0cQmdrBNj41tpvi/JEoAGrAgEDo4HF -MIHCMB0GA1UdDgQWBBS/X7fRzt0fhvRbVazc1xDCDqmI5zCBkgYDVR0jBIGKMIGHgBS/X7fRzt0f -hvRbVazc1xDCDqmI56FspGowaDELMAkGA1UEBhMCVVMxJTAjBgNVBAoTHFN0YXJmaWVsZCBUZWNo -bm9sb2dpZXMsIEluYy4xMjAwBgNVBAsTKVN0YXJmaWVsZCBDbGFzcyAyIENlcnRpZmljYXRpb24g -QXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAAWdP4id0ckaVaGs -afPzWdqbAYcaT1epoXkJKtv3L7IezMdeatiDh6GX70k1PncGQVhiv45YuApnP+yz3SFmH8lU+nLM -PUxA2IGvd56Deruix/U0F47ZEUD0/CwqTRV/p2JdLiXTAAsgGh1o+Re49L2L7ShZ3U0WixeDyLJl -xy16paq8U4Zt3VekyvggQQto8PT7dL5WXXp59fkdheMtlb71cZBDzI0fmgAKhynpVSJYACPq4xJD -KVtHCN2MQWplBqjlIapBtJUhlbl90TSrE9atvNziPTnNvT51cKEYWQPJIrSPnNVeKtelttQKbfi3 -QBFGmh95DmK/D5fs4C8fF5Q= ------END CERTIFICATE----- - -DigiCert Assured ID Root CA -=========================== ------BEGIN CERTIFICATE----- -MIIDtzCCAp+gAwIBAgIQDOfg5RfYRv6P5WD8G/AwOTANBgkqhkiG9w0BAQUFADBlMQswCQYDVQQG -EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSQw -IgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0EwHhcNMDYxMTEwMDAwMDAwWhcNMzEx -MTEwMDAwMDAwWjBlMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQL -ExB3d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0Ew -ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtDhXO5EOAXLGH87dg+XESpa7cJpSIqvTO -9SA5KFhgDPiA2qkVlTJhPLWxKISKityfCgyDF3qPkKyK53lTXDGEKvYPmDI2dsze3Tyoou9q+yHy -UmHfnyDXH+Kx2f4YZNISW1/5WBg1vEfNoTb5a3/UsDg+wRvDjDPZ2C8Y/igPs6eD1sNuRMBhNZYW -/lmci3Zt1/GiSw0r/wty2p5g0I6QNcZ4VYcgoc/lbQrISXwxmDNsIumH0DJaoroTghHtORedmTpy -oeb6pNnVFzF1roV9Iq4/AUaG9ih5yLHa5FcXxH4cDrC0kqZWs72yl+2qp/C3xag/lRbQ/6GW6whf -GHdPAgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRF -66Kv9JLLgjEtUYunpyGd823IDzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYunpyGd823IDzANBgkq -hkiG9w0BAQUFAAOCAQEAog683+Lt8ONyc3pklL/3cmbYMuRCdWKuh+vy1dneVrOfzM4UKLkNl2Bc -EkxY5NM9g0lFWJc1aRqoR+pWxnmrEthngYTffwk8lOa4JiwgvT2zKIn3X/8i4peEH+ll74fg38Fn -SbNd67IJKusm7Xi+fT8r87cmNW1fiQG2SVufAQWbqz0lwcy2f8Lxb4bG+mRo64EtlOtCt/qMHt1i -8b5QZ7dsvfPxH2sMNgcWfzd8qVttevESRmCD1ycEvkvOl77DZypoEd+A5wwzZr8TDRRu838fYxAe -+o0bJW1sj6W3YQGx0qMmoRBxna3iw/nDmVG3KwcIzi7mULKn+gpFL6Lw8g== ------END CERTIFICATE----- - -DigiCert Global Root CA -======================= ------BEGIN CERTIFICATE----- -MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBhMQswCQYDVQQG -EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSAw -HgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBDQTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAw -MDAwMDBaMGExCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3 -dy5kaWdpY2VydC5jb20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkq -hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsBCSDMAZOn -TjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97nh6Vfe63SKMI2tavegw5 -BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt43C/dxC//AH2hdmoRBBYMql1GNXRor5H -4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7PT19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y -7vrTC0LUq7dBMtoM1O/4gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQAB -o2MwYTAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbRTLtm -8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUwDQYJKoZIhvcNAQEF -BQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/EsrhMAtudXH/vTBH1jLuG2cenTnmCmr -EbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIt -tep3Sp+dWOIrWcBAI+0tKIJFPnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886 -UAb3LujEV0lsYSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk -CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4= ------END CERTIFICATE----- - -DigiCert High Assurance EV Root CA -================================== ------BEGIN CERTIFICATE----- -MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBsMQswCQYDVQQG -EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSsw -KQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5jZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAw -MFoXDTMxMTExMDAwMDAwMFowbDELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZ -MBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFu -Y2UgRVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm+9S75S0t -Mqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTWPNt0OKRKzE0lgvdKpVMS -OO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEMxChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3 -MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFBIk5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQ -NAQTXKFx01p8VdteZOE3hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUe -h10aUAsgEsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMB -Af8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaAFLE+w2kD+L9HAdSY -JhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3NecnzyIZgYIVyHbIUf4KmeqvxgydkAQ -V8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6zeM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFp -myPInngiK3BD41VHMWEZ71jFhS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkK -mNEVX58Svnw2Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe -vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep+OkuE6N36B9K ------END CERTIFICATE----- - -SwissSign Gold CA - G2 -====================== ------BEGIN CERTIFICATE----- -MIIFujCCA6KgAwIBAgIJALtAHEP1Xk+wMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNVBAYTAkNIMRUw -EwYDVQQKEwxTd2lzc1NpZ24gQUcxHzAdBgNVBAMTFlN3aXNzU2lnbiBHb2xkIENBIC0gRzIwHhcN -MDYxMDI1MDgzMDM1WhcNMzYxMDI1MDgzMDM1WjBFMQswCQYDVQQGEwJDSDEVMBMGA1UEChMMU3dp -c3NTaWduIEFHMR8wHQYDVQQDExZTd2lzc1NpZ24gR29sZCBDQSAtIEcyMIICIjANBgkqhkiG9w0B -AQEFAAOCAg8AMIICCgKCAgEAr+TufoskDhJuqVAtFkQ7kpJcyrhdhJJCEyq8ZVeCQD5XJM1QiyUq -t2/876LQwB8CJEoTlo8jE+YoWACjR8cGp4QjK7u9lit/VcyLwVcfDmJlD909Vopz2q5+bbqBHH5C -jCA12UNNhPqE21Is8w4ndwtrvxEvcnifLtg+5hg3Wipy+dpikJKVyh+c6bM8K8vzARO/Ws/BtQpg -vd21mWRTuKCWs2/iJneRjOBiEAKfNA+k1ZIzUd6+jbqEemA8atufK+ze3gE/bk3lUIbLtK/tREDF -ylqM2tIrfKjuvqblCqoOpd8FUrdVxyJdMmqXl2MT28nbeTZ7hTpKxVKJ+STnnXepgv9VHKVxaSvR -AiTysybUa9oEVeXBCsdtMDeQKuSeFDNeFhdVxVu1yzSJkvGdJo+hB9TGsnhQ2wwMC3wLjEHXuend -jIj3o02yMszYF9rNt85mndT9Xv+9lz4pded+p2JYryU0pUHHPbwNUMoDAw8IWh+Vc3hiv69yFGkO -peUDDniOJihC8AcLYiAQZzlG+qkDzAQ4embvIIO1jEpWjpEA/I5cgt6IoMPiaG59je883WX0XaxR -7ySArqpWl2/5rX3aYT+YdzylkbYcjCbaZaIJbcHiVOO5ykxMgI93e2CaHt+28kgeDrpOVG2Y4OGi -GqJ3UM/EY5LsRxmd6+ZrzsECAwEAAaOBrDCBqTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUw -AwEB/zAdBgNVHQ4EFgQUWyV7lqRlUX64OfPAeGZe6Drn8O4wHwYDVR0jBBgwFoAUWyV7lqRlUX64 -OfPAeGZe6Drn8O4wRgYDVR0gBD8wPTA7BglghXQBWQECAQEwLjAsBggrBgEFBQcCARYgaHR0cDov -L3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIBACe645R88a7A3hfm -5djV9VSwg/S7zV4Fe0+fdWavPOhWfvxyeDgD2StiGwC5+OlgzczOUYrHUDFu4Up+GC9pWbY9ZIEr -44OE5iKHjn3g7gKZYbge9LgriBIWhMIxkziWMaa5O1M/wySTVltpkuzFwbs4AOPsF6m43Md8AYOf -Mke6UiI0HTJ6CVanfCU2qT1L2sCCbwq7EsiHSycR+R4tx5M/nttfJmtS2S6K8RTGRI0Vqbe/vd6m -Gu6uLftIdxf+u+yvGPUqUfA5hJeVbG4bwyvEdGB5JbAKJ9/fXtI5z0V9QkvfsywexcZdylU6oJxp -mo/a77KwPJ+HbBIrZXAVUjEaJM9vMSNQH4xPjyPDdEFjHFWoFN0+4FFQz/EbMFYOkrCChdiDyyJk -vC24JdVUorgG6q2SpCSgwYa1ShNqR88uC1aVVMvOmttqtKay20EIhid392qgQmwLOM7XdVAyksLf -KzAiSNDVQTglXaTpXZ/GlHXQRf0wl0OPkKsKx4ZzYEppLd6leNcG2mqeSz53OiATIgHQv2ieY2Br -NU0LbbqhPcCT4H8js1WtciVORvnSFu+wZMEBnunKoGqYDs/YYPIvSbjkQuE4NRb0yG5P94FW6Lqj -viOvrv1vA+ACOzB2+httQc8Bsem4yWb02ybzOqR08kkkW8mw0FfB+j564ZfJ ------END CERTIFICATE----- - -SwissSign Silver CA - G2 -======================== ------BEGIN CERTIFICATE----- -MIIFvTCCA6WgAwIBAgIITxvUL1S7L0swDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCQ0gxFTAT -BgNVBAoTDFN3aXNzU2lnbiBBRzEhMB8GA1UEAxMYU3dpc3NTaWduIFNpbHZlciBDQSAtIEcyMB4X -DTA2MTAyNTA4MzI0NloXDTM2MTAyNTA4MzI0NlowRzELMAkGA1UEBhMCQ0gxFTATBgNVBAoTDFN3 -aXNzU2lnbiBBRzEhMB8GA1UEAxMYU3dpc3NTaWduIFNpbHZlciBDQSAtIEcyMIICIjANBgkqhkiG -9w0BAQEFAAOCAg8AMIICCgKCAgEAxPGHf9N4Mfc4yfjDmUO8x/e8N+dOcbpLj6VzHVxumK4DV644 -N0MvFz0fyM5oEMF4rhkDKxD6LHmD9ui5aLlV8gREpzn5/ASLHvGiTSf5YXu6t+WiE7brYT7QbNHm -+/pe7R20nqA1W6GSy/BJkv6FCgU+5tkL4k+73JU3/JHpMjUi0R86TieFnbAVlDLaYQ1HTWBCrpJH -6INaUFjpiou5XaHc3ZlKHzZnu0jkg7Y360g6rw9njxcH6ATK72oxh9TAtvmUcXtnZLi2kUpCe2Uu -MGoM9ZDulebyzYLs2aFK7PayS+VFheZteJMELpyCbTapxDFkH4aDCyr0NQp4yVXPQbBH6TCfmb5h -qAaEuSh6XzjZG6k4sIN/c8HDO0gqgg8hm7jMqDXDhBuDsz6+pJVpATqJAHgE2cn0mRmrVn5bi4Y5 -FZGkECwJMoBgs5PAKrYYC51+jUnyEEp/+dVGLxmSo5mnJqy7jDzmDrxHB9xzUfFwZC8I+bRHHTBs -ROopN4WSaGa8gzj+ezku01DwH/teYLappvonQfGbGHLy9YR0SslnxFSuSGTfjNFusB3hB48IHpmc -celM2KX3RxIfdNFRnobzwqIjQAtz20um53MGjMGg6cFZrEb65i/4z3GcRm25xBWNOHkDRUjvxF3X -CO6HOSKGsg0PWEP3calILv3q1h8CAwEAAaOBrDCBqTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/ -BAUwAwEB/zAdBgNVHQ4EFgQUF6DNweRBtjpbO8tFnb0cwpj6hlgwHwYDVR0jBBgwFoAUF6DNweRB -tjpbO8tFnb0cwpj6hlgwRgYDVR0gBD8wPTA7BglghXQBWQEDAQEwLjAsBggrBgEFBQcCARYgaHR0 -cDovL3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIBAHPGgeAn0i0P -4JUw4ppBf1AsX19iYamGamkYDHRJ1l2E6kFSGG9YrVBWIGrGvShpWJHckRE1qTodvBqlYJ7YH39F -kWnZfrt4csEGDyrOj4VwYaygzQu4OSlWhDJOhrs9xCrZ1x9y7v5RoSJBsXECYxqCsGKrXlcSH9/L -3XWgwF15kIwb4FDm3jH+mHtwX6WQ2K34ArZv02DdQEsixT2tOnqfGhpHkXkzuoLcMmkDlm4fS/Bx -/uNncqCxv1yL5PqZIseEuRuNI5c/7SXgz2W79WEE790eslpBIlqhn10s6FvJbakMDHiqYMZWjwFa -DGi8aRl5xB9+lwW/xekkUV7U1UtT7dkjWjYDZaPBA61BMPNGG4WQr2W11bHkFlt4dR2Xem1ZqSqP -e97Dh4kQmUlzeMg9vVE1dCrV8X5pGyq7O70luJpaPXJhkGaH7gzWTdQRdAtq/gsD/KNVV4n+Ssuu -WxcFyPKNIzFTONItaj+CuY0IavdeQXRuwxF+B6wpYJE/OMpXEA29MC/HpeZBoNquBYeaoKRlbEwJ -DIm6uNO5wJOKMPqN5ZprFQFOZ6raYlY+hAhm0sQ2fac+EPyI4NSA5QC9qvNOBqN6avlicuMJT+ub -DgEj8Z+7fNzcbBGXJbLytGMU0gYqZ4yD9c7qB9iaah7s5Aq7KkzrCWA5zspi2C5u ------END CERTIFICATE----- - -SecureTrust CA -============== ------BEGIN CERTIFICATE----- -MIIDuDCCAqCgAwIBAgIQDPCOXAgWpa1Cf/DrJxhZ0DANBgkqhkiG9w0BAQUFADBIMQswCQYDVQQG -EwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24xFzAVBgNVBAMTDlNlY3VyZVRy -dXN0IENBMB4XDTA2MTEwNzE5MzExOFoXDTI5MTIzMTE5NDA1NVowSDELMAkGA1UEBhMCVVMxIDAe -BgNVBAoTF1NlY3VyZVRydXN0IENvcnBvcmF0aW9uMRcwFQYDVQQDEw5TZWN1cmVUcnVzdCBDQTCC -ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKukgeWVzfX2FI7CT8rU4niVWJxB4Q2ZQCQX -OZEzZum+4YOvYlyJ0fwkW2Gz4BERQRwdbvC4u/jep4G6pkjGnx29vo6pQT64lO0pGtSO0gMdA+9t -DWccV9cGrcrI9f4Or2YlSASWC12juhbDCE/RRvgUXPLIXgGZbf2IzIaowW8xQmxSPmjL8xk037uH -GFaAJsTQ3MBv396gwpEWoGQRS0S8Hvbn+mPeZqx2pHGj7DaUaHp3pLHnDi+BeuK1cobvomuL8A/b -01k/unK8RCSc43Oz969XL0Imnal0ugBS8kvNU3xHCzaFDmapCJcWNFfBZveA4+1wVMeT4C4oFVmH -ursCAwEAAaOBnTCBmjATBgkrBgEEAYI3FAIEBh4EAEMAQTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/ -BAUwAwEB/zAdBgNVHQ4EFgQUQjK2FvoE/f5dS3rD/fdMQB1aQ68wNAYDVR0fBC0wKzApoCegJYYj -aHR0cDovL2NybC5zZWN1cmV0cnVzdC5jb20vU1RDQS5jcmwwEAYJKwYBBAGCNxUBBAMCAQAwDQYJ -KoZIhvcNAQEFBQADggEBADDtT0rhWDpSclu1pqNlGKa7UTt36Z3q059c4EVlew3KW+JwULKUBRSu -SceNQQcSc5R+DCMh/bwQf2AQWnL1mA6s7Ll/3XpvXdMc9P+IBWlCqQVxyLesJugutIxq/3HcuLHf -mbx8IVQr5Fiiu1cprp6poxkmD5kuCLDv/WnPmRoJjeOnnyvJNjR7JLN4TJUXpAYmHrZkUjZfYGfZ -nMUFdAvnZyPSCPyI6a6Lf+Ew9Dd+/cYy2i2eRDAwbO4H3tI0/NL/QPZL9GZGBlSm8jIKYyYwa5vR -3ItHuuG51WLQoqD0ZwV4KWMabwTW+MZMo5qxN7SN5ShLHZ4swrhovO0C7jE= ------END CERTIFICATE----- - -Secure Global CA -================ ------BEGIN CERTIFICATE----- -MIIDvDCCAqSgAwIBAgIQB1YipOjUiolN9BPI8PjqpTANBgkqhkiG9w0BAQUFADBKMQswCQYDVQQG -EwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBH -bG9iYWwgQ0EwHhcNMDYxMTA3MTk0MjI4WhcNMjkxMjMxMTk1MjA2WjBKMQswCQYDVQQGEwJVUzEg -MB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwg -Q0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvNS7YrGxVaQZx5RNoJLNP2MwhR/jx -YDiJiQPpvepeRlMJ3Fz1Wuj3RSoC6zFh1ykzTM7HfAo3fg+6MpjhHZevj8fcyTiW89sa/FHtaMbQ -bqR8JNGuQsiWUGMu4P51/pinX0kuleM5M2SOHqRfkNJnPLLZ/kG5VacJjnIFHovdRIWCQtBJwB1g -8NEXLJXr9qXBkqPFwqcIYA1gBBCWeZ4WNOaptvolRTnIHmX5k/Wq8VLcmZg9pYYaDDUz+kulBAYV -HDGA76oYa8J719rO+TMg1fW9ajMtgQT7sFzUnKPiXB3jqUJ1XnvUd+85VLrJChgbEplJL4hL/VBi -0XPnj3pDAgMBAAGjgZ0wgZowEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1Ud -EwEB/wQFMAMBAf8wHQYDVR0OBBYEFK9EBMJBfkiD2045AuzshHrmzsmkMDQGA1UdHwQtMCswKaAn -oCWGI2h0dHA6Ly9jcmwuc2VjdXJldHJ1c3QuY29tL1NHQ0EuY3JsMBAGCSsGAQQBgjcVAQQDAgEA -MA0GCSqGSIb3DQEBBQUAA4IBAQBjGghAfaReUw132HquHw0LURYD7xh8yOOvaliTFGCRsoTciE6+ -OYo68+aCiV0BN7OrJKQVDpI1WkpEXk5X+nXOH0jOZvQ8QCaSmGwb7iRGDBezUqXbpZGRzzfTb+cn -CDpOGR86p1hcF895P4vkp9MmI50mD1hp/Ed+stCNi5O/KU9DaXR2Z0vPB4zmAve14bRDtUstFJ/5 -3CYNv6ZHdAbYiNE6KTCEztI5gGIbqMdXSbxqVVFnFUq+NQfk1XWYN3kwFNspnWzFacxHVaIw98xc -f8LDmBxrThaA63p4ZUWiABqvDA1VZDRIuJK58bRQKfJPIx/abKwfROHdI3hRW8cW ------END CERTIFICATE----- - -COMODO Certification Authority -============================== ------BEGIN CERTIFICATE----- -MIIEHTCCAwWgAwIBAgIQToEtioJl4AsC7j41AkblPTANBgkqhkiG9w0BAQUFADCBgTELMAkGA1UE -BhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgG -A1UEChMRQ09NT0RPIENBIExpbWl0ZWQxJzAlBgNVBAMTHkNPTU9ETyBDZXJ0aWZpY2F0aW9uIEF1 -dGhvcml0eTAeFw0wNjEyMDEwMDAwMDBaFw0yOTEyMzEyMzU5NTlaMIGBMQswCQYDVQQGEwJHQjEb -MBkGA1UECBMSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFD -T01PRE8gQ0EgTGltaXRlZDEnMCUGA1UEAxMeQ09NT0RPIENlcnRpZmljYXRpb24gQXV0aG9yaXR5 -MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ECLi3LjkRv3UcEbVASY06m/weaKXTuH -+7uIzg3jLz8GlvCiKVCZrts7oVewdFFxze1CkU1B/qnI2GqGd0S7WWaXUF601CxwRM/aN5VCaTww -xHGzUvAhTaHYujl8HJ6jJJ3ygxaYqhZ8Q5sVW7euNJH+1GImGEaaP+vB+fGQV+useg2L23IwambV -4EajcNxo2f8ESIl33rXp+2dtQem8Ob0y2WIC8bGoPW43nOIv4tOiJovGuFVDiOEjPqXSJDlqR6sA -1KGzqSX+DT+nHbrTUcELpNqsOO9VUCQFZUaTNE8tja3G1CEZ0o7KBWFxB3NH5YoZEr0ETc5OnKVI -rLsm9wIDAQABo4GOMIGLMB0GA1UdDgQWBBQLWOWLxkwVN6RAqTCpIb5HNlpW/zAOBgNVHQ8BAf8E -BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zBJBgNVHR8EQjBAMD6gPKA6hjhodHRwOi8vY3JsLmNvbW9k -b2NhLmNvbS9DT01PRE9DZXJ0aWZpY2F0aW9uQXV0aG9yaXR5LmNybDANBgkqhkiG9w0BAQUFAAOC -AQEAPpiem/Yb6dc5t3iuHXIYSdOH5EOC6z/JqvWote9VfCFSZfnVDeFs9D6Mk3ORLgLETgdxb8CP -OGEIqB6BCsAvIC9Bi5HcSEW88cbeunZrM8gALTFGTO3nnc+IlP8zwFboJIYmuNg4ON8qa90SzMc/ -RxdMosIGlgnW2/4/PEZB31jiVg88O8EckzXZOFKs7sjsLjBOlDW0JB9LeGna8gI4zJVSk/BwJVmc -IGfE7vmLV2H0knZ9P4SNVbfo5azV8fUZVqZa+5Acr5Pr5RzUZ5ddBA6+C4OmF4O5MBKgxTMVBbkN -+8cFduPYSo38NBejxiEovjBFMR7HeL5YYTisO+IBZQ== ------END CERTIFICATE----- - -COMODO ECC Certification Authority -================================== ------BEGIN CERTIFICATE----- -MIICiTCCAg+gAwIBAgIQH0evqmIAcFBUTAGem2OZKjAKBggqhkjOPQQDAzCBhTELMAkGA1UEBhMC -R0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UE -ChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBB -dXRob3JpdHkwHhcNMDgwMzA2MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0Ix -GzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMR -Q09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRo -b3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQDR3svdcmCFYX7deSRFtSrYpn1PlILBs5BAH+X -4QokPB0BBO490o0JlwzgdeT6+3eKKvUDYEs2ixYjFq0JcfRK9ChQtP6IHG4/bC8vCVlbpVsLM5ni -wz2J+Wos77LTBumjQjBAMB0GA1UdDgQWBBR1cacZSBm8nZ3qQUfflMRId5nTeTAOBgNVHQ8BAf8E -BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjEA7wNbeqy3eApyt4jf/7VG -FAkK+qDmfQjGGoe9GKhzvSbKYAydzpmfz1wPMOG+FDHqAjAU9JM8SaczepBGR7NjfRObTrdvGDeA -U/7dIOA1mjbRxwG55tzd8/8dLDoWV9mSOdY= ------END CERTIFICATE----- - -Certigna -======== ------BEGIN CERTIFICATE----- -MIIDqDCCApCgAwIBAgIJAP7c4wEPyUj/MA0GCSqGSIb3DQEBBQUAMDQxCzAJBgNVBAYTAkZSMRIw -EAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hMB4XDTA3MDYyOTE1MTMwNVoXDTI3 -MDYyOTE1MTMwNVowNDELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCURoaW15b3RpczERMA8GA1UEAwwI -Q2VydGlnbmEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDIaPHJ1tazNHUmgh7stL7q -XOEm7RFHYeGifBZ4QCHkYJ5ayGPhxLGWkv8YbWkj4Sti993iNi+RB7lIzw7sebYs5zRLcAglozyH -GxnygQcPOJAZ0xH+hrTy0V4eHpbNgGzOOzGTtvKg0KmVEn2lmsxryIRWijOp5yIVUxbwzBfsV1/p -ogqYCd7jX5xv3EjjhQsVWqa6n6xI4wmy9/Qy3l40vhx4XUJbzg4ij02Q130yGLMLLGq/jj8UEYkg -DncUtT2UCIf3JR7VsmAA7G8qKCVuKj4YYxclPz5EIBb2JsglrgVKtOdjLPOMFlN+XPsRGgjBRmKf -Irjxwo1p3Po6WAbfAgMBAAGjgbwwgbkwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUGu3+QTmQ -tCRZvgHyUtVF9lo53BEwZAYDVR0jBF0wW4AUGu3+QTmQtCRZvgHyUtVF9lo53BGhOKQ2MDQxCzAJ -BgNVBAYTAkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hggkA/tzjAQ/J -SP8wDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIABzANBgkqhkiG9w0BAQUFAAOCAQEA -hQMeknH2Qq/ho2Ge6/PAD/Kl1NqV5ta+aDY9fm4fTIrv0Q8hbV6lUmPOEvjvKtpv6zf+EwLHyzs+ -ImvaYS5/1HI93TDhHkxAGYwP15zRgzB7mFncfca5DClMoTOi62c6ZYTTluLtdkVwj7Ur3vkj1klu -PBS1xp81HlDQwY9qcEQCYsuuHWhBp6pX6FOqB9IG9tUUBguRA3UsbHK1YZWaDYu5Def131TN3ubY -1gkIl2PlwS6wt0QmwCbAr1UwnjvVNioZBPRcHv/PLLf/0P2HQBHVESO7SMAhqaQoLf0V+LBOK/Qw -WyH8EZE0vkHve52Xdf+XlcCWWC/qu0bXu+TZLg== ------END CERTIFICATE----- - -ePKI Root Certification Authority -================================= ------BEGIN CERTIFICATE----- -MIIFsDCCA5igAwIBAgIQFci9ZUdcr7iXAF7kBtK8nTANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQG -EwJUVzEjMCEGA1UECgwaQ2h1bmdod2EgVGVsZWNvbSBDby4sIEx0ZC4xKjAoBgNVBAsMIWVQS0kg -Um9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNDEyMjAwMjMxMjdaFw0zNDEyMjAwMjMx -MjdaMF4xCzAJBgNVBAYTAlRXMSMwIQYDVQQKDBpDaHVuZ2h3YSBUZWxlY29tIENvLiwgTHRkLjEq -MCgGA1UECwwhZVBLSSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkqhkiG9w0B -AQEFAAOCAg8AMIICCgKCAgEA4SUP7o3biDN1Z82tH306Tm2d0y8U82N0ywEhajfqhFAHSyZbCUNs -IZ5qyNUD9WBpj8zwIuQf5/dqIjG3LBXy4P4AakP/h2XGtRrBp0xtInAhijHyl3SJCRImHJ7K2RKi -lTza6We/CKBk49ZCt0Xvl/T29de1ShUCWH2YWEtgvM3XDZoTM1PRYfl61dd4s5oz9wCGzh1NlDiv -qOx4UXCKXBCDUSH3ET00hl7lSM2XgYI1TBnsZfZrxQWh7kcT1rMhJ5QQCtkkO7q+RBNGMD+XPNjX -12ruOzjjK9SXDrkb5wdJfzcq+Xd4z1TtW0ado4AOkUPB1ltfFLqfpo0kR0BZv3I4sjZsN/+Z0V0O -WQqraffAsgRFelQArr5T9rXn4fg8ozHSqf4hUmTFpmfwdQcGlBSBVcYn5AGPF8Fqcde+S/uUWH1+ -ETOxQvdibBjWzwloPn9s9h6PYq2lY9sJpx8iQkEeb5mKPtf5P0B6ebClAZLSnT0IFaUQAS2zMnao -lQ2zepr7BxB4EW/hj8e6DyUadCrlHJhBmd8hh+iVBmoKs2pHdmX2Os+PYhcZewoozRrSgx4hxyy/ -vv9haLdnG7t4TY3OZ+XkwY63I2binZB1NJipNiuKmpS5nezMirH4JYlcWrYvjB9teSSnUmjDhDXi -Zo1jDiVN1Rmy5nk3pyKdVDECAwEAAaNqMGgwHQYDVR0OBBYEFB4M97Zn8uGSJglFwFU5Lnc/Qkqi -MAwGA1UdEwQFMAMBAf8wOQYEZyoHAAQxMC8wLQIBADAJBgUrDgMCGgUAMAcGBWcqAwAABBRFsMLH -ClZ87lt4DJX5GFPBphzYEDANBgkqhkiG9w0BAQUFAAOCAgEACbODU1kBPpVJufGBuvl2ICO1J2B0 -1GqZNF5sAFPZn/KmsSQHRGoqxqWOeBLoR9lYGxMqXnmbnwoqZ6YlPwZpVnPDimZI+ymBV3QGypzq -KOg4ZyYr8dW1P2WT+DZdjo2NQCCHGervJ8A9tDkPJXtoUHRVnAxZfVo9QZQlUgjgRywVMRnVvwdV -xrsStZf0X4OFunHB2WyBEXYKCrC/gpf36j36+uwtqSiUO1bd0lEursC9CBWMd1I0ltabrNMdjmEP -NXubrjlpC2JgQCA2j6/7Nu4tCEoduL+bXPjqpRugc6bY+G7gMwRfaKonh+3ZwZCc7b3jajWvY9+r -GNm65ulK6lCKD2GTHuItGeIwlDWSXQ62B68ZgI9HkFFLLk3dheLSClIKF5r8GrBQAuUBo2M3IUxE -xJtRmREOc5wGj1QupyheRDmHVi03vYVElOEMSyycw5KFNGHLD7ibSkNS/jQ6fbjpKdx2qcgw+BRx -gMYeNkh0IkFch4LoGHGLQYlE535YW6i4jRPpp2zDR+2zGp1iro2C6pSe3VkQw63d4k3jMdXH7Ojy -sP6SHhYKGvzZ8/gntsm+HbRsZJB/9OTEW9c3rkIO3aQab3yIVMUWbuF6aC74Or8NpDyJO3inTmOD -BCEIZ43ygknQW/2xzQ+DhNQ+IIX3Sj0rnP0qCglN6oH4EZw= ------END CERTIFICATE----- - -certSIGN ROOT CA -================ ------BEGIN CERTIFICATE----- -MIIDODCCAiCgAwIBAgIGIAYFFnACMA0GCSqGSIb3DQEBBQUAMDsxCzAJBgNVBAYTAlJPMREwDwYD -VQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBDQTAeFw0wNjA3MDQxNzIwMDRa -Fw0zMTA3MDQxNzIwMDRaMDsxCzAJBgNVBAYTAlJPMREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UE -CxMQY2VydFNJR04gUk9PVCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALczuX7I -JUqOtdu0KBuqV5Do0SLTZLrTk+jUrIZhQGpgV2hUhE28alQCBf/fm5oqrl0Hj0rDKH/v+yv6efHH -rfAQUySQi2bJqIirr1qjAOm+ukbuW3N7LBeCgV5iLKECZbO9xSsAfsT8AzNXDe3i+s5dRdY4zTW2 -ssHQnIFKquSyAVwdj1+ZxLGt24gh65AIgoDzMKND5pCCrlUoSe1b16kQOA7+j0xbm0bqQfWwCHTD -0IgztnzXdN/chNFDDnU5oSVAKOp4yw4sLjmdjItuFhwvJoIQ4uNllAoEwF73XVv4EOLQunpL+943 -AAAaWyjj0pxzPjKHmKHJUS/X3qwzs08CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8B -Af8EBAMCAcYwHQYDVR0OBBYEFOCMm9slSbPxfIbWskKHC9BroNnkMA0GCSqGSIb3DQEBBQUAA4IB -AQA+0hyJLjX8+HXd5n9liPRyTMks1zJO890ZeUe9jjtbkw9QSSQTaxQGcu8J06Gh40CEyecYMnQ8 -SG4Pn0vU9x7Tk4ZkVJdjclDVVc/6IJMCopvDI5NOFlV2oHB5bc0hH88vLbwZ44gx+FkagQnIl6Z0 -x2DEW8xXjrJ1/RsCCdtZb3KTafcxQdaIOL+Hsr0Wefmq5L6IJd1hJyMctTEHBDa0GpC9oHRxUIlt -vBTjD4au8as+x6AJzKNI0eDbZOeStc+vckNwi/nDhDwTqn6Sm1dTk/pwwpEOMfmbZ13pljheX7Nz -TogVZ96edhBiIL5VaZVDADlN9u6wWk5JRFRYX0KD ------END CERTIFICATE----- - -NetLock Arany (Class Gold) Főtanúsítvány -======================================== ------BEGIN CERTIFICATE----- -MIIEFTCCAv2gAwIBAgIGSUEs5AAQMA0GCSqGSIb3DQEBCwUAMIGnMQswCQYDVQQGEwJIVTERMA8G -A1UEBwwIQnVkYXBlc3QxFTATBgNVBAoMDE5ldExvY2sgS2Z0LjE3MDUGA1UECwwuVGFuw7pzw610 -dsOhbnlraWFkw7NrIChDZXJ0aWZpY2F0aW9uIFNlcnZpY2VzKTE1MDMGA1UEAwwsTmV0TG9jayBB -cmFueSAoQ2xhc3MgR29sZCkgRsWRdGFuw7pzw610dsOhbnkwHhcNMDgxMjExMTUwODIxWhcNMjgx -MjA2MTUwODIxWjCBpzELMAkGA1UEBhMCSFUxETAPBgNVBAcMCEJ1ZGFwZXN0MRUwEwYDVQQKDAxO -ZXRMb2NrIEtmdC4xNzA1BgNVBAsMLlRhbsO6c8OtdHbDoW55a2lhZMOzayAoQ2VydGlmaWNhdGlv -biBTZXJ2aWNlcykxNTAzBgNVBAMMLE5ldExvY2sgQXJhbnkgKENsYXNzIEdvbGQpIEbFkXRhbsO6 -c8OtdHbDoW55MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxCRec75LbRTDofTjl5Bu -0jBFHjzuZ9lk4BqKf8owyoPjIMHj9DrTlF8afFttvzBPhCf2nx9JvMaZCpDyD/V/Q4Q3Y1GLeqVw -/HpYzY6b7cNGbIRwXdrzAZAj/E4wqX7hJ2Pn7WQ8oLjJM2P+FpD/sLj916jAwJRDC7bVWaaeVtAk -H3B5r9s5VA1lddkVQZQBr17s9o3x/61k/iCa11zr/qYfCGSji3ZVrR47KGAuhyXoqq8fxmRGILdw -fzzeSNuWU7c5d+Qa4scWhHaXWy+7GRWF+GmF9ZmnqfI0p6m2pgP8b4Y9VHx2BJtr+UBdADTHLpl1 -neWIA6pN+APSQnbAGwIDAKiLo0UwQzASBgNVHRMBAf8ECDAGAQH/AgEEMA4GA1UdDwEB/wQEAwIB -BjAdBgNVHQ4EFgQUzPpnk/C2uNClwB7zU/2MU9+D15YwDQYJKoZIhvcNAQELBQADggEBAKt/7hwW -qZw8UQCgwBEIBaeZ5m8BiFRhbvG5GK1Krf6BQCOUL/t1fC8oS2IkgYIL9WHxHG64YTjrgfpioTta -YtOUZcTh5m2C+C8lcLIhJsFyUR+MLMOEkMNaj7rP9KdlpeuY0fsFskZ1FSNqb4VjMIDw1Z4fKRzC -bLBQWV2QWzuoDTDPv31/zvGdg73JRm4gpvlhUbohL3u+pRVjodSVh/GeufOJ8z2FuLjbvrW5Kfna -NwUASZQDhETnv0Mxz3WLJdH0pmT1kvarBes96aULNmLazAZfNou2XjG4Kvte9nHfRCaexOYNkbQu -dZWAUWpLMKawYqGT8ZvYzsRjdT9ZR7E= ------END CERTIFICATE----- - -SecureSign RootCA11 -=================== ------BEGIN CERTIFICATE----- -MIIDbTCCAlWgAwIBAgIBATANBgkqhkiG9w0BAQUFADBYMQswCQYDVQQGEwJKUDErMCkGA1UEChMi -SmFwYW4gQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcywgSW5jLjEcMBoGA1UEAxMTU2VjdXJlU2lnbiBS -b290Q0ExMTAeFw0wOTA0MDgwNDU2NDdaFw0yOTA0MDgwNDU2NDdaMFgxCzAJBgNVBAYTAkpQMSsw -KQYDVQQKEyJKYXBhbiBDZXJ0aWZpY2F0aW9uIFNlcnZpY2VzLCBJbmMuMRwwGgYDVQQDExNTZWN1 -cmVTaWduIFJvb3RDQTExMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA/XeqpRyQBTvL -TJszi1oURaTnkBbR31fSIRCkF/3frNYfp+TbfPfs37gD2pRY/V1yfIw/XwFndBWW4wI8h9uuywGO -wvNmxoVF9ALGOrVisq/6nL+k5tSAMJjzDbaTj6nU2DbysPyKyiyhFTOVMdrAG/LuYpmGYz+/3ZMq -g6h2uRMft85OQoWPIucuGvKVCbIFtUROd6EgvanyTgp9UK31BQ1FT0Zx/Sg+U/sE2C3XZR1KG/rP -O7AxmjVuyIsG0wCR8pQIZUyxNAYAeoni8McDWc/V1uinMrPmmECGxc0nEovMe863ETxiYAcjPitA -bpSACW22s293bzUIUPsCh8U+iQIDAQABo0IwQDAdBgNVHQ4EFgQUW/hNT7KlhtQ60vFjmqC+CfZX -t94wDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAKCh -OBZmLqdWHyGcBvod7bkixTgm2E5P7KN/ed5GIaGHd48HCJqypMWvDzKYC3xmKbabfSVSSUOrTC4r -bnpwrxYO4wJs+0LmGJ1F2FXI6Dvd5+H0LgscNFxsWEr7jIhQX5Ucv+2rIrVls4W6ng+4reV6G4pQ -Oh29Dbx7VFALuUKvVaAYga1lme++5Jy/xIWrQbJUb9wlze144o4MjQlJ3WN7WmmWAiGovVJZ6X01 -y8hSyn+B/tlr0/cR7SXf+Of5pPpyl4RTDaXQMhhRdlkUbA/r7F+AjHVDg8OFmP9Mni0N5HeDk061 -lgeLKBObjBmNQSdJQO7e5iNEOdyhIta6A/I= ------END CERTIFICATE----- - -Microsec e-Szigno Root CA 2009 -============================== ------BEGIN CERTIFICATE----- -MIIECjCCAvKgAwIBAgIJAMJ+QwRORz8ZMA0GCSqGSIb3DQEBCwUAMIGCMQswCQYDVQQGEwJIVTER -MA8GA1UEBwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0ZC4xJzAlBgNVBAMMHk1pY3Jv -c2VjIGUtU3ppZ25vIFJvb3QgQ0EgMjAwOTEfMB0GCSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5o -dTAeFw0wOTA2MTYxMTMwMThaFw0yOTEyMzAxMTMwMThaMIGCMQswCQYDVQQGEwJIVTERMA8GA1UE -BwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUt -U3ppZ25vIFJvb3QgQ0EgMjAwOTEfMB0GCSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5odTCCASIw -DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOn4j/NjrdqG2KfgQvvPkd6mJviZpWNwrZuuyjNA -fW2WbqEORO7hE52UQlKavXWFdCyoDh2Tthi3jCyoz/tccbna7P7ofo/kLx2yqHWH2Leh5TvPmUpG -0IMZfcChEhyVbUr02MelTTMuhTlAdX4UfIASmFDHQWe4oIBhVKZsTh/gnQ4H6cm6M+f+wFUoLAKA -pxn1ntxVUwOXewdI/5n7N4okxFnMUBBjjqqpGrCEGob5X7uxUG6k0QrM1XF+H6cbfPVTbiJfyyvm -1HxdrtbCxkzlBQHZ7Vf8wSN5/PrIJIOV87VqUQHQd9bpEqH5GoP7ghu5sJf0dgYzQ0mg/wu1+rUC -AwEAAaOBgDB+MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTLD8bf -QkPMPcu1SCOhGnqmKrs0aDAfBgNVHSMEGDAWgBTLD8bfQkPMPcu1SCOhGnqmKrs0aDAbBgNVHREE -FDASgRBpbmZvQGUtc3ppZ25vLmh1MA0GCSqGSIb3DQEBCwUAA4IBAQDJ0Q5eLtXMs3w+y/w9/w0o -lZMEyL/azXm4Q5DwpL7v8u8hmLzU1F0G9u5C7DBsoKqpyvGvivo/C3NqPuouQH4frlRheesuCDfX -I/OMn74dseGkddug4lQUsbocKaQY9hK6ohQU4zE1yED/t+AFdlfBHFny+L/k7SViXITwfn4fs775 -tyERzAMBVnCnEJIeGzSBHq2cGsMEPO0CYdYeBvNfOofyK/FFh+U9rNHHV4S9a67c2Pm2G2JwCz02 -yULyMtd6YebS2z3PyKnJm9zbWETXbzivf3jTo60adbocwTZ8jx5tHMN1Rq41Bab2XD0h7lbwyYIi -LXpUq3DDfSJlgnCW ------END CERTIFICATE----- - -GlobalSign Root CA - R3 -======================= ------BEGIN CERTIFICATE----- -MIIDXzCCAkegAwIBAgILBAAAAAABIVhTCKIwDQYJKoZIhvcNAQELBQAwTDEgMB4GA1UECxMXR2xv -YmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkdsb2Jh -bFNpZ24wHhcNMDkwMzE4MTAwMDAwWhcNMjkwMzE4MTAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxT -aWduIFJvb3QgQ0EgLSBSMzETMBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2ln -bjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMwldpB5BngiFvXAg7aEyiie/QV2EcWt -iHL8RgJDx7KKnQRfJMsuS+FggkbhUqsMgUdwbN1k0ev1LKMPgj0MK66X17YUhhB5uzsTgHeMCOFJ -0mpiLx9e+pZo34knlTifBtc+ycsmWQ1z3rDI6SYOgxXG71uL0gRgykmmKPZpO/bLyCiR5Z2KYVc3 -rHQU3HTgOu5yLy6c+9C7v/U9AOEGM+iCK65TpjoWc4zdQQ4gOsC0p6Hpsk+QLjJg6VfLuQSSaGjl -OCZgdbKfd/+RFO+uIEn8rUAVSNECMWEZXriX7613t2Saer9fwRPvm2L7DWzgVGkWqQPabumDk3F2 -xmmFghcCAwEAAaNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYE -FI/wS3+oLkUkrk1Q+mOai97i3Ru8MA0GCSqGSIb3DQEBCwUAA4IBAQBLQNvAUKr+yAzv95ZURUm7 -lgAJQayzE4aGKAczymvmdLm6AC2upArT9fHxD4q/c2dKg8dEe3jgr25sbwMpjjM5RcOO5LlXbKr8 -EpbsU8Yt5CRsuZRj+9xTaGdWPoO4zzUhw8lo/s7awlOqzJCK6fBdRoyV3XpYKBovHd7NADdBj+1E -bddTKJd+82cEHhXXipa0095MJ6RMG3NzdvQXmcIfeg7jLQitChws/zyrVQ4PkX4268NXSb7hLi18 -YIvDQVETI53O9zJrlAGomecsMx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7r -kpeDMdmztcpHWD9f ------END CERTIFICATE----- - -Autoridad de Certificacion Firmaprofesional CIF A62634068 -========================================================= ------BEGIN CERTIFICATE----- -MIIGFDCCA/ygAwIBAgIIU+w77vuySF8wDQYJKoZIhvcNAQEFBQAwUTELMAkGA1UEBhMCRVMxQjBA -BgNVBAMMOUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1hcHJvZmVzaW9uYWwgQ0lGIEE2 -MjYzNDA2ODAeFw0wOTA1MjAwODM4MTVaFw0zMDEyMzEwODM4MTVaMFExCzAJBgNVBAYTAkVTMUIw -QAYDVQQDDDlBdXRvcmlkYWQgZGUgQ2VydGlmaWNhY2lvbiBGaXJtYXByb2Zlc2lvbmFsIENJRiBB -NjI2MzQwNjgwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKlmuO6vj78aI14H9M2uDD -Utd9thDIAl6zQyrET2qyyhxdKJp4ERppWVevtSBC5IsP5t9bpgOSL/UR5GLXMnE42QQMcas9UX4P -B99jBVzpv5RvwSmCwLTaUbDBPLutN0pcyvFLNg4kq7/DhHf9qFD0sefGL9ItWY16Ck6WaVICqjaY -7Pz6FIMMNx/Jkjd/14Et5cS54D40/mf0PmbR0/RAz15iNA9wBj4gGFrO93IbJWyTdBSTo3OxDqqH -ECNZXyAFGUftaI6SEspd/NYrspI8IM/hX68gvqB2f3bl7BqGYTM+53u0P6APjqK5am+5hyZvQWyI -plD9amML9ZMWGxmPsu2bm8mQ9QEM3xk9Dz44I8kvjwzRAv4bVdZO0I08r0+k8/6vKtMFnXkIoctX -MbScyJCyZ/QYFpM6/EfY0XiWMR+6KwxfXZmtY4laJCB22N/9q06mIqqdXuYnin1oKaPnirjaEbsX -LZmdEyRG98Xi2J+Of8ePdG1asuhy9azuJBCtLxTa/y2aRnFHvkLfuwHb9H/TKI8xWVvTyQKmtFLK -bpf7Q8UIJm+K9Lv9nyiqDdVF8xM6HdjAeI9BZzwelGSuewvF6NkBiDkal4ZkQdU7hwxu+g/GvUgU -vzlN1J5Bto+WHWOWk9mVBngxaJ43BjuAiUVhOSPHG0SjFeUc+JIwuwIDAQABo4HvMIHsMBIGA1Ud -EwEB/wQIMAYBAf8CAQEwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRlzeurNR4APn7VdMActHNH -DhpkLzCBpgYDVR0gBIGeMIGbMIGYBgRVHSAAMIGPMC8GCCsGAQUFBwIBFiNodHRwOi8vd3d3LmZp -cm1hcHJvZmVzaW9uYWwuY29tL2NwczBcBggrBgEFBQcCAjBQHk4AUABhAHMAZQBvACAAZABlACAA -bABhACAAQgBvAG4AYQBuAG8AdgBhACAANAA3ACAAQgBhAHIAYwBlAGwAbwBuAGEAIAAwADgAMAAx -ADcwDQYJKoZIhvcNAQEFBQADggIBABd9oPm03cXF661LJLWhAqvdpYhKsg9VSytXjDvlMd3+xDLx -51tkljYyGOylMnfX40S2wBEqgLk9am58m9Ot/MPWo+ZkKXzR4Tgegiv/J2Wv+xYVxC5xhOW1//qk -R71kMrv2JYSiJ0L1ILDCExARzRAVukKQKtJE4ZYm6zFIEv0q2skGz3QeqUvVhyj5eTSSPi5E6PaP -T481PyWzOdxjKpBrIF/EUhJOlywqrJ2X3kjyo2bbwtKDlaZmp54lD+kLM5FlClrD2VQS3a/DTg4f -Jl4N3LON7NWBcN7STyQF82xO9UxJZo3R/9ILJUFI/lGExkKvgATP0H5kSeTy36LssUzAKh3ntLFl -osS88Zj0qnAHY7S42jtM+kAiMFsRpvAFDsYCA0irhpuF3dvd6qJ2gHN99ZwExEWN57kci57q13XR -crHedUTnQn3iV2t93Jm8PYMo6oCTjcVMZcFwgbg4/EMxsvYDNEeyrPsiBsse3RdHHF9mudMaotoR -saS8I8nkvof/uZS2+F0gStRf571oe2XyFR7SOqkt6dhrJKyXWERHrVkY8SFlcN7ONGCoQPHzPKTD -KCOM/iczQ0CgFzzr6juwcqajuUpLXhZI9LK8yIySxZ2frHI2vDSANGupi5LAuBft7HZT9SQBjLMi -6Et8Vcad+qMUu2WFbm5PEn4KPJ2V ------END CERTIFICATE----- - -Izenpe.com -========== ------BEGIN CERTIFICATE----- -MIIF8TCCA9mgAwIBAgIQALC3WhZIX7/hy/WL1xnmfTANBgkqhkiG9w0BAQsFADA4MQswCQYDVQQG -EwJFUzEUMBIGA1UECgwLSVpFTlBFIFMuQS4xEzARBgNVBAMMCkl6ZW5wZS5jb20wHhcNMDcxMjEz -MTMwODI4WhcNMzcxMjEzMDgyNzI1WjA4MQswCQYDVQQGEwJFUzEUMBIGA1UECgwLSVpFTlBFIFMu -QS4xEzARBgNVBAMMCkl6ZW5wZS5jb20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDJ -03rKDx6sp4boFmVqscIbRTJxldn+EFvMr+eleQGPicPK8lVx93e+d5TzcqQsRNiekpsUOqHnJJAK -ClaOxdgmlOHZSOEtPtoKct2jmRXagaKH9HtuJneJWK3W6wyyQXpzbm3benhB6QiIEn6HLmYRY2xU -+zydcsC8Lv/Ct90NduM61/e0aL6i9eOBbsFGb12N4E3GVFWJGjMxCrFXuaOKmMPsOzTFlUFpfnXC -PCDFYbpRR6AgkJOhkEvzTnyFRVSa0QUmQbC1TR0zvsQDyCV8wXDbO/QJLVQnSKwv4cSsPsjLkkxT -OTcj7NMB+eAJRE1NZMDhDVqHIrytG6P+JrUV86f8hBnp7KGItERphIPzidF0BqnMC9bC3ieFUCbK -F7jJeodWLBoBHmy+E60QrLUk9TiRodZL2vG70t5HtfG8gfZZa88ZU+mNFctKy6lvROUbQc/hhqfK -0GqfvEyNBjNaooXlkDWgYlwWTvDjovoDGrQscbNYLN57C9saD+veIR8GdwYDsMnvmfzAuU8Lhij+ -0rnq49qlw0dpEuDb8PYZi+17cNcC1u2HGCgsBCRMd+RIihrGO5rUD8r6ddIBQFqNeb+Lz0vPqhbB -leStTIo+F5HUsWLlguWABKQDfo2/2n+iD5dPDNMN+9fR5XJ+HMh3/1uaD7euBUbl8agW7EekFwID -AQABo4H2MIHzMIGwBgNVHREEgagwgaWBD2luZm9AaXplbnBlLmNvbaSBkTCBjjFHMEUGA1UECgw+ -SVpFTlBFIFMuQS4gLSBDSUYgQTAxMzM3MjYwLVJNZXJjLlZpdG9yaWEtR2FzdGVpeiBUMTA1NSBG -NjIgUzgxQzBBBgNVBAkMOkF2ZGEgZGVsIE1lZGl0ZXJyYW5lbyBFdG9yYmlkZWEgMTQgLSAwMTAx -MCBWaXRvcmlhLUdhc3RlaXowDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0O -BBYEFB0cZQ6o8iV7tJHP5LGx5r1VdGwFMA0GCSqGSIb3DQEBCwUAA4ICAQB4pgwWSp9MiDrAyw6l -Fn2fuUhfGI8NYjb2zRlrrKvV9pF9rnHzP7MOeIWblaQnIUdCSnxIOvVFfLMMjlF4rJUT3sb9fbga -kEyrkgPH7UIBzg/YsfqikuFgba56awmqxinuaElnMIAkejEWOVt+8Rwu3WwJrfIxwYJOubv5vr8q -hT/AQKM6WfxZSzwoJNu0FXWuDYi6LnPAvViH5ULy617uHjAimcs30cQhbIHsvm0m5hzkQiCeR7Cs -g1lwLDXWrzY0tM07+DKo7+N4ifuNRSzanLh+QBxh5z6ikixL8s36mLYp//Pye6kfLqCTVyvehQP5 -aTfLnnhqBbTFMXiJ7HqnheG5ezzevh55hM6fcA5ZwjUukCox2eRFekGkLhObNA5me0mrZJfQRsN5 -nXJQY6aYWwa9SG3YOYNw6DXwBdGqvOPbyALqfP2C2sJbUjWumDqtujWTI6cfSN01RpiyEGjkpTHC -ClguGYEQyVB1/OpaFs4R1+7vUIgtYf8/QnMFlEPVjjxOAToZpR9GTnfQXeWBIiGH/pR9hNiTrdZo -Q0iy2+tzJOeRf1SktoA+naM8THLCV8Sg1Mw4J87VBp6iSNnpn86CcDaTmjvfliHjWbcM2pE38P1Z -WrOZyGlsQyYBNWNgVYkDOnXYukrZVP/u3oDYLdE41V4tC5h9Pmzb/CaIxw== ------END CERTIFICATE----- - -Go Daddy Root Certificate Authority - G2 -======================================== ------BEGIN CERTIFICATE----- -MIIDxTCCAq2gAwIBAgIBADANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMxEDAOBgNVBAgT -B0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoTEUdvRGFkZHkuY29tLCBJbmMu -MTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5 -MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgYMxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6 -b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjExMC8G -A1UEAxMoR28gRGFkZHkgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZI -hvcNAQEBBQADggEPADCCAQoCggEBAL9xYgjx+lk09xvJGKP3gElY6SKDE6bFIEMBO4Tx5oVJnyfq -9oQbTqC023CYxzIBsQU+B07u9PpPL1kwIuerGVZr4oAH/PMWdYA5UXvl+TW2dE6pjYIT5LY/qQOD -+qK+ihVqf94Lw7YZFAXK6sOoBJQ7RnwyDfMAZiLIjWltNowRGLfTshxgtDj6AozO091GB94KPutd -fMh8+7ArU6SSYmlRJQVhGkSBjCypQ5Yj36w6gZoOKcUcqeldHraenjAKOc7xiID7S13MMuyFYkMl -NAJWJwGRtDtwKj9useiciAF9n9T521NtYJ2/LOdYq7hfRvzOxBsDPAnrSTFcaUaz4EcCAwEAAaNC -MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFDqahQcQZyi27/a9 -BUFuIMGU2g/eMA0GCSqGSIb3DQEBCwUAA4IBAQCZ21151fmXWWcDYfF+OwYxdS2hII5PZYe096ac -vNjpL9DbWu7PdIxztDhC2gV7+AJ1uP2lsdeu9tfeE8tTEH6KRtGX+rcuKxGrkLAngPnon1rpN5+r -5N9ss4UXnT3ZJE95kTXWXwTrgIOrmgIttRD02JDHBHNA7XIloKmf7J6raBKZV8aPEjoJpL1E/QYV -N8Gb5DKj7Tjo2GTzLH4U/ALqn83/B2gX2yKQOC16jdFU8WnjXzPKej17CuPKf1855eJ1usV2GDPO -LPAvTK33sefOT6jEm0pUBsV/fdUID+Ic/n4XuKxe9tQWskMJDE32p2u0mYRlynqI4uJEvlz36hz1 ------END CERTIFICATE----- - -Starfield Root Certificate Authority - G2 -========================================= ------BEGIN CERTIFICATE----- -MIID3TCCAsWgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMxEDAOBgNVBAgT -B0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoTHFN0YXJmaWVsZCBUZWNobm9s -b2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVsZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0 -eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgY8xCzAJBgNVBAYTAlVTMRAw -DgYDVQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQg -VGVjaG5vbG9naWVzLCBJbmMuMTIwMAYDVQQDEylTdGFyZmllbGQgUm9vdCBDZXJ0aWZpY2F0ZSBB -dXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL3twQP89o/8ArFv -W59I2Z154qK3A2FWGMNHttfKPTUuiUP3oWmb3ooa/RMgnLRJdzIpVv257IzdIvpy3Cdhl+72WoTs -bhm5iSzchFvVdPtrX8WJpRBSiUZV9Lh1HOZ/5FSuS/hVclcCGfgXcVnrHigHdMWdSL5stPSksPNk -N3mSwOxGXn/hbVNMYq/NHwtjuzqd+/x5AJhhdM8mgkBj87JyahkNmcrUDnXMN/uLicFZ8WJ/X7Nf -ZTD4p7dNdloedl40wOiWVpmKs/B/pM293DIxfJHP4F8R+GuqSVzRmZTRouNjWwl2tVZi4Ut0HZbU -JtQIBFnQmA4O5t78w+wfkPECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC -AQYwHQYDVR0OBBYEFHwMMh+n2TB/xH1oo2Kooc6rB1snMA0GCSqGSIb3DQEBCwUAA4IBAQARWfol -TwNvlJk7mh+ChTnUdgWUXuEok21iXQnCoKjUsHU48TRqneSfioYmUeYs0cYtbpUgSpIB7LiKZ3sx -4mcujJUDJi5DnUox9g61DLu34jd/IroAow57UvtruzvE03lRTs2Q9GcHGcg8RnoNAX3FWOdt5oUw -F5okxBDgBPfg8n/Uqgr/Qh037ZTlZFkSIHc40zI+OIF1lnP6aI+xy84fxez6nH7PfrHxBy22/L/K -pL/QlwVKvOoYKAKQvVR4CSFx09F9HdkWsKlhPdAKACL8x3vLCWRFCztAgfd9fDL1mMpYjn0q7pBZ -c2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0 ------END CERTIFICATE----- - -Starfield Services Root Certificate Authority - G2 -================================================== ------BEGIN CERTIFICATE----- -MIID7zCCAtegAwIBAgIBADANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMCVVMxEDAOBgNVBAgT -B0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoTHFN0YXJmaWVsZCBUZWNobm9s -b2dpZXMsIEluYy4xOzA5BgNVBAMTMlN0YXJmaWVsZCBTZXJ2aWNlcyBSb290IENlcnRpZmljYXRl -IEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgZgxCzAJBgNV -BAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxT -dGFyZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTswOQYDVQQDEzJTdGFyZmllbGQgU2VydmljZXMg -Um9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC -AQoCggEBANUMOsQq+U7i9b4Zl1+OiFOxHz/Lz58gE20pOsgPfTz3a3Y4Y9k2YKibXlwAgLIvWX/2 -h/klQ4bnaRtSmpDhcePYLQ1Ob/bISdm28xpWriu2dBTrz/sm4xq6HZYuajtYlIlHVv8loJNwU4Pa -hHQUw2eeBGg6345AWh1KTs9DkTvnVtYAcMtS7nt9rjrnvDH5RfbCYM8TWQIrgMw0R9+53pBlbQLP -LJGmpufehRhJfGZOozptqbXuNC66DQO4M99H67FrjSXZm86B0UVGMpZwh94CDklDhbZsc7tk6mFB -rMnUVN+HL8cisibMn1lUaJ/8viovxFUcdUBgF4UCVTmLfwUCAwEAAaNCMEAwDwYDVR0TAQH/BAUw -AwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJxfAN+qAdcwKziIorhtSpzyEZGDMA0GCSqG -SIb3DQEBCwUAA4IBAQBLNqaEd2ndOxmfZyMIbw5hyf2E3F/YNoHN2BtBLZ9g3ccaaNnRbobhiCPP -E95Dz+I0swSdHynVv/heyNXBve6SbzJ08pGCL72CQnqtKrcgfU28elUSwhXqvfdqlS5sdJ/PHLTy -xQGjhdByPq1zqwubdQxtRbeOlKyWN7Wg0I8VRw7j6IPdj/3vQQF3zCepYoUz8jcI73HPdwbeyBkd -iEDPfUYd/x7H4c7/I9vG+o1VTqkC50cRRj70/b17KSa7qWFiNyi2LSr2EIZkyXCn0q23KXB56jza -YyWf/Wi3MOxw+3WKt21gZ7IeyLnp2KhvAotnDU0mV3HaIPzBSlCNsSi6 ------END CERTIFICATE----- - -AffirmTrust Commercial -====================== ------BEGIN CERTIFICATE----- -MIIDTDCCAjSgAwIBAgIId3cGJyapsXwwDQYJKoZIhvcNAQELBQAwRDELMAkGA1UEBhMCVVMxFDAS -BgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBDb21tZXJjaWFsMB4XDTEw -MDEyOTE0MDYwNloXDTMwMTIzMTE0MDYwNlowRDELMAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmly -bVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBDb21tZXJjaWFsMIIBIjANBgkqhkiG9w0BAQEF -AAOCAQ8AMIIBCgKCAQEA9htPZwcroRX1BiLLHwGy43NFBkRJLLtJJRTWzsO3qyxPxkEylFf6Eqdb -DuKPHx6GGaeqtS25Xw2Kwq+FNXkyLbscYjfysVtKPcrNcV/pQr6U6Mje+SJIZMblq8Yrba0F8PrV -C8+a5fBQpIs7R6UjW3p6+DM/uO+Zl+MgwdYoic+U+7lF7eNAFxHUdPALMeIrJmqbTFeurCA+ukV6 -BfO9m2kVrn1OIGPENXY6BwLJN/3HR+7o8XYdcxXyl6S1yHp52UKqK39c/s4mT6NmgTWvRLpUHhww -MmWd5jyTXlBOeuM61G7MGvv50jeuJCqrVwMiKA1JdX+3KNp1v47j3A55MQIDAQABo0IwQDAdBgNV -HQ4EFgQUnZPGU4teyq8/nx4P5ZmVvCT2lI8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC -AQYwDQYJKoZIhvcNAQELBQADggEBAFis9AQOzcAN/wr91LoWXym9e2iZWEnStB03TX8nfUYGXUPG -hi4+c7ImfU+TqbbEKpqrIZcUsd6M06uJFdhrJNTxFq7YpFzUf1GO7RgBsZNjvbz4YYCanrHOQnDi -qX0GJX0nof5v7LMeJNrjS1UaADs1tDvZ110w/YETifLCBivtZ8SOyUOyXGsViQK8YvxO8rUzqrJv -0wqiUOP2O+guRMLbZjipM1ZI8W0bM40NjD9gN53Tym1+NH4Nn3J2ixufcv1SNUFFApYvHLKac0kh -sUlHRUe072o0EclNmsxZt9YCnlpOZbWUrhvfKbAW8b8Angc6F2S1BLUjIZkKlTuXfO8= ------END CERTIFICATE----- - -AffirmTrust Networking -====================== ------BEGIN CERTIFICATE----- -MIIDTDCCAjSgAwIBAgIIfE8EORzUmS0wDQYJKoZIhvcNAQEFBQAwRDELMAkGA1UEBhMCVVMxFDAS -BgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBOZXR3b3JraW5nMB4XDTEw -MDEyOTE0MDgyNFoXDTMwMTIzMTE0MDgyNFowRDELMAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmly -bVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBOZXR3b3JraW5nMIIBIjANBgkqhkiG9w0BAQEF -AAOCAQ8AMIIBCgKCAQEAtITMMxcua5Rsa2FSoOujz3mUTOWUgJnLVWREZY9nZOIG41w3SfYvm4SE -Hi3yYJ0wTsyEheIszx6e/jarM3c1RNg1lho9Nuh6DtjVR6FqaYvZ/Ls6rnla1fTWcbuakCNrmreI -dIcMHl+5ni36q1Mr3Lt2PpNMCAiMHqIjHNRqrSK6mQEubWXLviRmVSRLQESxG9fhwoXA3hA/Pe24 -/PHxI1Pcv2WXb9n5QHGNfb2V1M6+oF4nI979ptAmDgAp6zxG8D1gvz9Q0twmQVGeFDdCBKNwV6gb -h+0t+nvujArjqWaJGctB+d1ENmHP4ndGyH329JKBNv3bNPFyfvMMFr20FQIDAQABo0IwQDAdBgNV -HQ4EFgQUBx/S55zawm6iQLSwelAQUHTEyL0wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC -AQYwDQYJKoZIhvcNAQEFBQADggEBAIlXshZ6qML91tmbmzTCnLQyFE2npN/svqe++EPbkTfOtDIu -UFUaNU52Q3Eg75N3ThVwLofDwR1t3Mu1J9QsVtFSUzpE0nPIxBsFZVpikpzuQY0x2+c06lkh1QF6 -12S4ZDnNye2v7UsDSKegmQGA3GWjNq5lWUhPgkvIZfFXHeVZLgo/bNjR9eUJtGxUAArgFU2HdW23 -WJZa3W3SAKD0m0i+wzekujbgfIeFlxoVot4uolu9rxj5kFDNcFn4J2dHy8egBzp90SxdbBk6ZrV9 -/ZFvgrG+CJPbFEfxojfHRZ48x3evZKiT3/Zpg4Jg8klCNO1aAFSFHBY2kgxc+qatv9s= ------END CERTIFICATE----- - -AffirmTrust Premium -=================== ------BEGIN CERTIFICATE----- -MIIFRjCCAy6gAwIBAgIIbYwURrGmCu4wDQYJKoZIhvcNAQEMBQAwQTELMAkGA1UEBhMCVVMxFDAS -BgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1UcnVzdCBQcmVtaXVtMB4XDTEwMDEy -OTE0MTAzNloXDTQwMTIzMTE0MTAzNlowQTELMAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRy -dXN0MRwwGgYDVQQDDBNBZmZpcm1UcnVzdCBQcmVtaXVtMIICIjANBgkqhkiG9w0BAQEFAAOCAg8A -MIICCgKCAgEAxBLfqV/+Qd3d9Z+K4/as4Tx4mrzY8H96oDMq3I0gW64tb+eT2TZwamjPjlGjhVtn -BKAQJG9dKILBl1fYSCkTtuG+kU3fhQxTGJoeJKJPj/CihQvL9Cl/0qRY7iZNyaqoe5rZ+jjeRFcV -5fiMyNlI4g0WJx0eyIOFJbe6qlVBzAMiSy2RjYvmia9mx+n/K+k8rNrSs8PhaJyJ+HoAVt70VZVs -+7pk3WKL3wt3MutizCaam7uqYoNMtAZ6MMgpv+0GTZe5HMQxK9VfvFMSF5yZVylmd2EhMQcuJUmd -GPLu8ytxjLW6OQdJd/zvLpKQBY0tL3d770O/Nbua2Plzpyzy0FfuKE4mX4+QaAkvuPjcBukumj5R -p9EixAqnOEhss/n/fauGV+O61oV4d7pD6kh/9ti+I20ev9E2bFhc8e6kGVQa9QPSdubhjL08s9NI -S+LI+H+SqHZGnEJlPqQewQcDWkYtuJfzt9WyVSHvutxMAJf7FJUnM7/oQ0dG0giZFmA7mn7S5u04 -6uwBHjxIVkkJx0w3AJ6IDsBz4W9m6XJHMD4Q5QsDyZpCAGzFlH5hxIrff4IaC1nEWTJ3s7xgaVY5 -/bQGeyzWZDbZvUjthB9+pSKPKrhC9IK31FOQeE4tGv2Bb0TXOwF0lkLgAOIua+rF7nKsu7/+6qqo -+Nz2snmKtmcCAwEAAaNCMEAwHQYDVR0OBBYEFJ3AZ6YMItkm9UWrpmVSESfYRaxjMA8GA1UdEwEB -/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBDAUAA4ICAQCzV00QYk465KzquByv -MiPIs0laUZx2KI15qldGF9X1Uva3ROgIRL8YhNILgM3FEv0AVQVhh0HctSSePMTYyPtwni94loMg -Nt58D2kTiKV1NpgIpsbfrM7jWNa3Pt668+s0QNiigfV4Py/VpfzZotReBA4Xrf5B8OWycvpEgjNC -6C1Y91aMYj+6QrCcDFx+LmUmXFNPALJ4fqENmS2NuB2OosSw/WDQMKSOyARiqcTtNd56l+0OOF6S -L5Nwpamcb6d9Ex1+xghIsV5n61EIJenmJWtSKZGc0jlzCFfemQa0W50QBuHCAKi4HEoCChTQwUHK -+4w1IX2COPKpVJEZNZOUbWo6xbLQu4mGk+ibyQ86p3q4ofB4Rvr8Ny/lioTz3/4E2aFooC8k4gmV -BtWVyuEklut89pMFu+1z6S3RdTnX5yTb2E5fQ4+e0BQ5v1VwSJlXMbSc7kqYA5YwH2AG7hsj/oFg -IxpHYoWlzBk0gG+zrBrjn/B7SK3VAdlntqlyk+otZrWyuOQ9PLLvTIzq6we/qzWaVYa8GKa1qF60 -g2xraUDTn9zxw2lrueFtCfTxqlB2Cnp9ehehVZZCmTEJ3WARjQUwfuaORtGdFNrHF+QFlozEJLUb -zxQHskD4o55BhrwE0GuWyCqANP2/7waj3VjFhT0+j/6eKeC2uAloGRwYQw== ------END CERTIFICATE----- - -AffirmTrust Premium ECC -======================= ------BEGIN CERTIFICATE----- -MIIB/jCCAYWgAwIBAgIIdJclisc/elQwCgYIKoZIzj0EAwMwRTELMAkGA1UEBhMCVVMxFDASBgNV -BAoMC0FmZmlybVRydXN0MSAwHgYDVQQDDBdBZmZpcm1UcnVzdCBQcmVtaXVtIEVDQzAeFw0xMDAx -MjkxNDIwMjRaFw00MDEyMzExNDIwMjRaMEUxCzAJBgNVBAYTAlVTMRQwEgYDVQQKDAtBZmZpcm1U -cnVzdDEgMB4GA1UEAwwXQWZmaXJtVHJ1c3QgUHJlbWl1bSBFQ0MwdjAQBgcqhkjOPQIBBgUrgQQA -IgNiAAQNMF4bFZ0D0KF5Nbc6PJJ6yhUczWLznCZcBz3lVPqj1swS6vQUX+iOGasvLkjmrBhDeKzQ -N8O9ss0s5kfiGuZjuD0uL3jET9v0D6RoTFVya5UdThhClXjMNzyR4ptlKymjQjBAMB0GA1UdDgQW -BBSaryl6wBE1NSZRMADDav5A1a7WPDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAK -BggqhkjOPQQDAwNnADBkAjAXCfOHiFBar8jAQr9HX/VsaobgxCd05DhT1wV/GzTjxi+zygk8N53X -57hG8f2h4nECMEJZh0PUUd+60wkyWs6Iflc9nF9Ca/UHLbXwgpP5WW+uZPpY5Yse42O+tYHNbwKM -eQ== ------END CERTIFICATE----- - -Certum Trusted Network CA -========================= ------BEGIN CERTIFICATE----- -MIIDuzCCAqOgAwIBAgIDBETAMA0GCSqGSIb3DQEBBQUAMH4xCzAJBgNVBAYTAlBMMSIwIAYDVQQK -ExlVbml6ZXRvIFRlY2hub2xvZ2llcyBTLkEuMScwJQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlv -biBBdXRob3JpdHkxIjAgBgNVBAMTGUNlcnR1bSBUcnVzdGVkIE5ldHdvcmsgQ0EwHhcNMDgxMDIy -MTIwNzM3WhcNMjkxMjMxMTIwNzM3WjB+MQswCQYDVQQGEwJQTDEiMCAGA1UEChMZVW5pemV0byBU -ZWNobm9sb2dpZXMgUy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRpZmljYXRpb24gQXV0aG9yaXR5 -MSIwIAYDVQQDExlDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENBMIIBIjANBgkqhkiG9w0BAQEFAAOC -AQ8AMIIBCgKCAQEA4/t9o3K6wvDJFIf1awFO4W5AB7ptJ11/91sts1rHUV+rpDKmYYe2bg+G0jAC -l/jXaVehGDldamR5xgFZrDwxSjh80gTSSyjoIF87B6LMTXPb865Px1bVWqeWifrzq2jUI4ZZJ88J -J7ysbnKDHDBy3+Ci6dLhdHUZvSqeexVUBBvXQzmtVSjF4hq79MDkrjhJM8x2hZ85RdKknvISjFH4 -fOQtf/WsX+sWn7Et0brMkUJ3TCXJkDhv2/DM+44el1k+1WBO5gUo7Ul5E0u6SNsv+XLTOcr+H9g0 -cvW0QM8xAcPs3hEtF10fuFDRXhmnad4HMyjKUJX5p1TLVIZQRan5SQIDAQABo0IwQDAPBgNVHRMB -Af8EBTADAQH/MB0GA1UdDgQWBBQIds3LB/8k9sXN7buQvOKEN0Z19zAOBgNVHQ8BAf8EBAMCAQYw -DQYJKoZIhvcNAQEFBQADggEBAKaorSLOAT2mo/9i0Eidi15ysHhE49wcrwn9I0j6vSrEuVUEtRCj -jSfeC4Jj0O7eDDd5QVsisrCaQVymcODU0HfLI9MA4GxWL+FpDQ3Zqr8hgVDZBqWo/5U30Kr+4rP1 -mS1FhIrlQgnXdAIv94nYmem8J9RHjboNRhx3zxSkHLmkMcScKHQDNP8zGSal6Q10tz6XxnboJ5aj -Zt3hrvJBW8qYVoNzcOSGGtIxQbovvi0TWnZvTuhOgQ4/WwMioBK+ZlgRSssDxLQqKi2WF+A5VLxI -03YnnZotBqbJ7DnSq9ufmgsnAjUpsUCV5/nonFWIGUbWtzT1fs45mtk48VH3Tyw= ------END CERTIFICATE----- - -TWCA Root Certification Authority -================================= ------BEGIN CERTIFICATE----- -MIIDezCCAmOgAwIBAgIBATANBgkqhkiG9w0BAQUFADBfMQswCQYDVQQGEwJUVzESMBAGA1UECgwJ -VEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NBIFJvb3QgQ2VydGlmaWNh -dGlvbiBBdXRob3JpdHkwHhcNMDgwODI4MDcyNDMzWhcNMzAxMjMxMTU1OTU5WjBfMQswCQYDVQQG -EwJUVzESMBAGA1UECgwJVEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NB -IFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK -AoIBAQCwfnK4pAOU5qfeCTiRShFAh6d8WWQUe7UREN3+v9XAu1bihSX0NXIP+FPQQeFEAcK0HMMx -QhZHhTMidrIKbw/lJVBPhYa+v5guEGcevhEFhgWQxFnQfHgQsIBct+HHK3XLfJ+utdGdIzdjp9xC -oi2SBBtQwXu4PhvJVgSLL1KbralW6cH/ralYhzC2gfeXRfwZVzsrb+RH9JlF/h3x+JejiB03HFyP -4HYlmlD4oFT/RJB2I9IyxsOrBr/8+7/zrX2SYgJbKdM1o5OaQ2RgXbL6Mv87BK9NQGr5x+PvI/1r -y+UPizgN7gr8/g+YnzAx3WxSZfmLgb4i4RxYA7qRG4kHAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIB -BjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqOFsmjd6LWvJPelSDGRjjCDWmujANBgkqhkiG -9w0BAQUFAAOCAQEAPNV3PdrfibqHDAhUaiBQkr6wQT25JmSDCi/oQMCXKCeCMErJk/9q56YAf4lC -mtYR5VPOL8zy2gXE/uJQxDqGfczafhAJO5I1KlOy/usrBdlsXebQ79NqZp4VKIV66IIArB6nCWlW -QtNoURi+VJq/REG6Sb4gumlc7rh3zc5sH62Dlhh9DrUUOYTxKOkto557HnpyWoOzeW/vtPzQCqVY -T0bf+215WfKEIlKuD8z7fDvnaspHYcN6+NOSBB+4IIThNlQWx0DeO4pz3N/GCUzf7Nr/1FNCocny -Yh0igzyXxfkZYiesZSLX0zzG5Y6yU8xJzrww/nsOM5D77dIUkR8Hrw== ------END CERTIFICATE----- - -Security Communication RootCA2 -============================== ------BEGIN CERTIFICATE----- -MIIDdzCCAl+gAwIBAgIBADANBgkqhkiG9w0BAQsFADBdMQswCQYDVQQGEwJKUDElMCMGA1UEChMc -U0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEnMCUGA1UECxMeU2VjdXJpdHkgQ29tbXVuaWNh -dGlvbiBSb290Q0EyMB4XDTA5MDUyOTA1MDAzOVoXDTI5MDUyOTA1MDAzOVowXTELMAkGA1UEBhMC -SlAxJTAjBgNVBAoTHFNFQ09NIFRydXN0IFN5c3RlbXMgQ08uLExURC4xJzAlBgNVBAsTHlNlY3Vy -aXR5IENvbW11bmljYXRpb24gUm9vdENBMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB -ANAVOVKxUrO6xVmCxF1SrjpDZYBLx/KWvNs2l9amZIyoXvDjChz335c9S672XewhtUGrzbl+dp++ -+T42NKA7wfYxEUV0kz1XgMX5iZnK5atq1LXaQZAQwdbWQonCv/Q4EpVMVAX3NuRFg3sUZdbcDE3R -3n4MqzvEFb46VqZab3ZpUql6ucjrappdUtAtCms1FgkQhNBqyjoGADdH5H5XTz+L62e4iKrFvlNV -spHEfbmwhRkGeC7bYRr6hfVKkaHnFtWOojnflLhwHyg/i/xAXmODPIMqGplrz95Zajv8bxbXH/1K -EOtOghY6rCcMU/Gt1SSwawNQwS08Ft1ENCcadfsCAwEAAaNCMEAwHQYDVR0OBBYEFAqFqXdlBZh8 -QIH4D5csOPEK7DzPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEB -CwUAA4IBAQBMOqNErLlFsceTfsgLCkLfZOoc7llsCLqJX2rKSpWeeo8HxdpFcoJxDjrSzG+ntKEj -u/Ykn8sX/oymzsLS28yN/HH8AynBbF0zX2S2ZTuJbxh2ePXcokgfGT+Ok+vx+hfuzU7jBBJV1uXk -3fs+BXziHV7Gp7yXT2g69ekuCkO2r1dcYmh8t/2jioSgrGK+KwmHNPBqAbubKVY8/gA3zyNs8U6q -tnRGEmyR7jTV7JqR50S+kDFy1UkC9gLl9B/rfNmWVan/7Ir5mUf/NVoCqgTLiluHcSmRvaS0eg29 -mvVXIwAHIRc/SjnRBUkLp7Y3gaVdjKozXoEofKd9J+sAro03 ------END CERTIFICATE----- - -Actalis Authentication Root CA -============================== ------BEGIN CERTIFICATE----- -MIIFuzCCA6OgAwIBAgIIVwoRl0LE48wwDQYJKoZIhvcNAQELBQAwazELMAkGA1UEBhMCSVQxDjAM -BgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8wMzM1ODUyMDk2NzEnMCUGA1UE -AwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290IENBMB4XDTExMDkyMjExMjIwMloXDTMwMDky -MjExMjIwMlowazELMAkGA1UEBhMCSVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlz -IFMucC5BLi8wMzM1ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290 -IENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAp8bEpSmkLO/lGMWwUKNvUTufClrJ -wkg4CsIcoBh/kbWHuUA/3R1oHwiD1S0eiKD4j1aPbZkCkpAW1V8IbInX4ay8IMKx4INRimlNAJZa -by/ARH6jDuSRzVju3PvHHkVH3Se5CAGfpiEd9UEtL0z9KK3giq0itFZljoZUj5NDKd45RnijMCO6 -zfB9E1fAXdKDa0hMxKufgFpbOr3JpyI/gCczWw63igxdBzcIy2zSekciRDXFzMwujt0q7bd9Zg1f -YVEiVRvjRuPjPdA1YprbrxTIW6HMiRvhMCb8oJsfgadHHwTrozmSBp+Z07/T6k9QnBn+locePGX2 -oxgkg4YQ51Q+qDp2JE+BIcXjDwL4k5RHILv+1A7TaLndxHqEguNTVHnd25zS8gebLra8Pu2Fbe8l -EfKXGkJh90qX6IuxEAf6ZYGyojnP9zz/GPvG8VqLWeICrHuS0E4UT1lF9gxeKF+w6D9Fz8+vm2/7 -hNN3WpVvrJSEnu68wEqPSpP4RCHiMUVhUE4Q2OM1fEwZtN4Fv6MGn8i1zeQf1xcGDXqVdFUNaBr8 -EBtiZJ1t4JWgw5QHVw0U5r0F+7if5t+L4sbnfpb2U8WANFAoWPASUHEXMLrmeGO89LKtmyuy/uE5 -jF66CyCU3nuDuP/jVo23Eek7jPKxwV2dpAtMK9myGPW1n0sCAwEAAaNjMGEwHQYDVR0OBBYEFFLY -iDrIn3hm7YnzezhwlMkCAjbQMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUUtiIOsifeGbt -ifN7OHCUyQICNtAwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQALe3KHwGCmSUyI -WOYdiPcUZEim2FgKDk8TNd81HdTtBjHIgT5q1d07GjLukD0R0i70jsNjLiNmsGe+b7bAEzlgqqI0 -JZN1Ut6nna0Oh4lScWoWPBkdg/iaKWW+9D+a2fDzWochcYBNy+A4mz+7+uAwTc+G02UQGRjRlwKx -K3JCaKygvU5a2hi/a5iB0P2avl4VSM0RFbnAKVy06Ij3Pjaut2L9HmLecHgQHEhb2rykOLpn7VU+ -Xlff1ANATIGk0k9jpwlCCRT8AKnCgHNPLsBA2RF7SOp6AsDT6ygBJlh0wcBzIm2Tlf05fbsq4/aC -4yyXX04fkZT6/iyj2HYauE2yOE+b+h1IYHkm4vP9qdCa6HCPSXrW5b0KDtst842/6+OkfcvHlXHo -2qN8xcL4dJIEG4aspCJTQLas/kx2z/uUMsA1n3Y/buWQbqCmJqK4LL7RK4X9p2jIugErsWx0Hbhz -lefut8cl8ABMALJ+tguLHPPAUJ4lueAI3jZm/zel0btUZCzJJ7VLkn5l/9Mt4blOvH+kQSGQQXem -OR/qnuOf0GZvBeyqdn6/axag67XH/JJULysRJyU3eExRarDzzFhdFPFqSBX/wge2sY0PjlxQRrM9 -vwGYT7JZVEc+NHt4bVaTLnPqZih4zR0Uv6CPLy64Lo7yFIrM6bV8+2ydDKXhlg== ------END CERTIFICATE----- - -Buypass Class 2 Root CA -======================= ------BEGIN CERTIFICATE----- -MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEdMBsGA1UECgwU -QnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3MgQ2xhc3MgMiBSb290IENBMB4X -DTEwMTAyNjA4MzgwM1oXDTQwMTAyNjA4MzgwM1owTjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1 -eXBhc3MgQVMtOTgzMTYzMzI3MSAwHgYDVQQDDBdCdXlwYXNzIENsYXNzIDIgUm9vdCBDQTCCAiIw -DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANfHXvfBB9R3+0Mh9PT1aeTuMgHbo4Yf5FkNuud1 -g1Lr6hxhFUi7HQfKjK6w3Jad6sNgkoaCKHOcVgb/S2TwDCo3SbXlzwx87vFKu3MwZfPVL4O2fuPn -9Z6rYPnT8Z2SdIrkHJasW4DptfQxh6NR/Md+oW+OU3fUl8FVM5I+GC911K2GScuVr1QGbNgGE41b -/+EmGVnAJLqBcXmQRFBoJJRfuLMR8SlBYaNByyM21cHxMlAQTn/0hpPshNOOvEu/XAFOBz3cFIqU -CqTqc/sLUegTBxj6DvEr0VQVfTzh97QZQmdiXnfgolXsttlpF9U6r0TtSsWe5HonfOV116rLJeff -awrbD02TTqigzXsu8lkBarcNuAeBfos4GzjmCleZPe4h6KP1DBbdi+w0jpwqHAAVF41og9JwnxgI -zRFo1clrUs3ERo/ctfPYV3Me6ZQ5BL/T3jjetFPsaRyifsSP5BtwrfKi+fv3FmRmaZ9JUaLiFRhn -Bkp/1Wy1TbMz4GHrXb7pmA8y1x1LPC5aAVKRCfLf6o3YBkBjqhHk/sM3nhRSP/TizPJhk9H9Z2vX -Uq6/aKtAQ6BXNVN48FP4YUIHZMbXb5tMOA1jrGKvNouicwoN9SG9dKpN6nIDSdvHXx1iY8f93ZHs -M+71bbRuMGjeyNYmsHVee7QHIJihdjK4TWxPAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYD -VR0OBBYEFMmAd+BikoL1RpzzuvdMw964o605MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsF -AAOCAgEAU18h9bqwOlI5LJKwbADJ784g7wbylp7ppHR/ehb8t/W2+xUbP6umwHJdELFx7rxP462s -A20ucS6vxOOto70MEae0/0qyexAQH6dXQbLArvQsWdZHEIjzIVEpMMpghq9Gqx3tOluwlN5E40EI -osHsHdb9T7bWR9AUC8rmyrV7d35BH16Dx7aMOZawP5aBQW9gkOLo+fsicdl9sz1Gv7SEr5AcD48S -aq/v7h56rgJKihcrdv6sVIkkLE8/trKnToyokZf7KcZ7XC25y2a2t6hbElGFtQl+Ynhw/qlqYLYd -DnkM/crqJIByw5c/8nerQyIKx+u2DISCLIBrQYoIwOula9+ZEsuK1V6ADJHgJgg2SMX6OBE1/yWD -LfJ6v9r9jv6ly0UsH8SIU653DtmadsWOLB2jutXsMq7Aqqz30XpN69QH4kj3Io6wpJ9qzo6ysmD0 -oyLQI+uUWnpp3Q+/QFesa1lQ2aOZ4W7+jQF5JyMV3pKdewlNWudLSDBaGOYKbeaP4NK75t98biGC -wWg5TbSYWGZizEqQXsP6JwSxeRV0mcy+rSDeJmAc61ZRpqPq5KM/p/9h3PFaTWwyI0PurKju7koS -CTxdccK+efrCh2gdC/1cacwG0Jp9VJkqyTkaGa9LKkPzY11aWOIv4x3kqdbQCtCev9eBCfHJxyYN -rJgWVqA= ------END CERTIFICATE----- - -Buypass Class 3 Root CA -======================= ------BEGIN CERTIFICATE----- -MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEdMBsGA1UECgwU -QnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3MgQ2xhc3MgMyBSb290IENBMB4X -DTEwMTAyNjA4Mjg1OFoXDTQwMTAyNjA4Mjg1OFowTjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1 -eXBhc3MgQVMtOTgzMTYzMzI3MSAwHgYDVQQDDBdCdXlwYXNzIENsYXNzIDMgUm9vdCBDQTCCAiIw -DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAKXaCpUWUOOV8l6ddjEGMnqb8RB2uACatVI2zSRH -sJ8YZLya9vrVediQYkwiL944PdbgqOkcLNt4EemOaFEVcsfzM4fkoF0LXOBXByow9c3EN3coTRiR -5r/VUv1xLXA+58bEiuPwKAv0dpihi4dVsjoT/Lc+JzeOIuOoTyrvYLs9tznDDgFHmV0ST9tD+leh -7fmdvhFHJlsTmKtdFoqwNxxXnUX/iJY2v7vKB3tvh2PX0DJq1l1sDPGzbjniazEuOQAnFN44wOwZ -ZoYS6J1yFhNkUsepNxz9gjDthBgd9K5c/3ATAOux9TN6S9ZV+AWNS2mw9bMoNlwUxFFzTWsL8TQH -2xc519woe2v1n/MuwU8XKhDzzMro6/1rqy6any2CbgTUUgGTLT2G/H783+9CHaZr77kgxve9oKeV -/afmiSTYzIw0bOIjL9kSGiG5VZFvC5F5GQytQIgLcOJ60g7YaEi7ghM5EFjp2CoHxhLbWNvSO1UQ -RwUVZ2J+GGOmRj8JDlQyXr8NYnon74Do29lLBlo3WiXQCBJ31G8JUJc9yB3D34xFMFbG02SrZvPA -Xpacw8Tvw3xrizp5f7NJzz3iiZ+gMEuFuZyUJHmPfWupRWgPK9Dx2hzLabjKSWJtyNBjYt1gD1iq -j6G8BaVmos8bdrKEZLFMOVLAMLrwjEsCsLa3AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYD -VR0OBBYEFEe4zf/lb+74suwvTg75JbCOPGvDMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsF -AAOCAgEAACAjQTUEkMJAYmDv4jVM1z+s4jSQuKFvdvoWFqRINyzpkMLyPPgKn9iB5btb2iUspKdV -cSQy9sgL8rxq+JOssgfCX5/bzMiKqr5qb+FJEMwx14C7u8jYog5kV+qi9cKpMRXSIGrs/CIBKM+G -uIAeqcwRpTzyFrNHnfzSgCHEy9BHcEGhyoMZCCxt8l13nIoUE9Q2HJLw5QY33KbmkJs4j1xrG0aG -Q0JfPgEHU1RdZX33inOhmlRaHylDFCfChQ+1iHsaO5S3HWCntZznKWlXWpuTekMwGwPXYshApqr8 -ZORK15FTAaggiG6cX0S5y2CBNOxv033aSF/rtJC8LakcC6wc1aJoIIAE1vyxjy+7SjENSoYc6+I2 -KSb12tjE8nVhz36udmNKekBlk4f4HoCMhuWG1o8O/FMsYOgWYRqiPkN7zTlgVGr18okmAWiDSKIz -6MkEkbIRNBE+6tBDGR8Dk5AM/1E9V/RBbuHLoL7ryWPNbczk+DaqaJ3tvV2XcEQNtg413OEMXbug -UZTLfhbrES+jkkXITHHZvMmZUldGL1DPvTVp9D0VzgalLA8+9oG6lLvDu79leNKGef9JOxqDDPDe -eOzI8k1MGt6CKfjBWtrt7uYnXuhF0J0cUahoq0Tj0Itq4/g7u9xN12TyUb7mqqta6THuBrxzvxNi -Cp/HuZc= ------END CERTIFICATE----- - -T-TeleSec GlobalRoot Class 3 -============================ ------BEGIN CERTIFICATE----- -MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoM -IlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBU -cnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDMwHhcNMDgx -MDAxMTAyOTU2WhcNMzMxMDAxMjM1OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lz -dGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBD -ZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDMwggEiMA0GCSqGSIb3 -DQEBAQUAA4IBDwAwggEKAoIBAQC9dZPwYiJvJK7genasfb3ZJNW4t/zN8ELg63iIVl6bmlQdTQyK -9tPPcPRStdiTBONGhnFBSivwKixVA9ZIw+A5OO3yXDw/RLyTPWGrTs0NvvAgJ1gORH8EGoel15YU -NpDQSXuhdfsaa3Ox+M6pCSzyU9XDFES4hqX2iys52qMzVNn6chr3IhUciJFrf2blw2qAsCTz34ZF -iP0Zf3WHHx+xGwpzJFu5ZeAsVMhg02YXP+HMVDNzkQI6pn97djmiH5a2OK61yJN0HZ65tOVgnS9W -0eDrXltMEnAMbEQgqxHY9Bn20pxSN+f6tsIxO0rUFJmtxxr1XV/6B7h8DR/Wgx6zAgMBAAGjQjBA -MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS1A/d2O2GCahKqGFPr -AyGUv/7OyjANBgkqhkiG9w0BAQsFAAOCAQEAVj3vlNW92nOyWL6ukK2YJ5f+AbGwUgC4TeQbIXQb -fsDuXmkqJa9c1h3a0nnJ85cp4IaH3gRZD/FZ1GSFS5mvJQQeyUapl96Cshtwn5z2r3Ex3XsFpSzT -ucpH9sry9uetuUg/vBa3wW306gmv7PO15wWeph6KU1HWk4HMdJP2udqmJQV0eVp+QD6CSyYRMG7h -P0HHRwA11fXT91Q+gT3aSWqas+8QPebrb9HIIkfLzM8BMZLZGOMivgkeGj5asuRrDFR6fUNOuIml -e9eiPZaGzPImNC1qkp2aGtAw4l1OBLBfiyB+d8E9lYLRRpo7PHi4b6HQDWSieB4pTpPDpFQUWw== ------END CERTIFICATE----- - -D-TRUST Root Class 3 CA 2 2009 -============================== ------BEGIN CERTIFICATE----- -MIIEMzCCAxugAwIBAgIDCYPzMA0GCSqGSIb3DQEBCwUAME0xCzAJBgNVBAYTAkRFMRUwEwYDVQQK -DAxELVRydXN0IEdtYkgxJzAlBgNVBAMMHkQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgMjAwOTAe -Fw0wOTExMDUwODM1NThaFw0yOTExMDUwODM1NThaME0xCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxE -LVRydXN0IEdtYkgxJzAlBgNVBAMMHkQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgMjAwOTCCASIw -DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANOySs96R+91myP6Oi/WUEWJNTrGa9v+2wBoqOAD -ER03UAifTUpolDWzU9GUY6cgVq/eUXjsKj3zSEhQPgrfRlWLJ23DEE0NkVJD2IfgXU42tSHKXzlA -BF9bfsyjxiupQB7ZNoTWSPOSHjRGICTBpFGOShrvUD9pXRl/RcPHAY9RySPocq60vFYJfxLLHLGv -KZAKyVXMD9O0Gu1HNVpK7ZxzBCHQqr0ME7UAyiZsxGsMlFqVlNpQmvH/pStmMaTJOKDfHR+4CS7z -p+hnUquVH+BGPtikw8paxTGA6Eian5Rp/hnd2HN8gcqW3o7tszIFZYQ05ub9VxC1X3a/L7AQDcUC -AwEAAaOCARowggEWMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFP3aFMSfMN4hvR5COfyrYyNJ -4PGEMA4GA1UdDwEB/wQEAwIBBjCB0wYDVR0fBIHLMIHIMIGAoH6gfIZ6bGRhcDovL2RpcmVjdG9y -eS5kLXRydXN0Lm5ldC9DTj1ELVRSVVNUJTIwUm9vdCUyMENsYXNzJTIwMyUyMENBJTIwMiUyMDIw -MDksTz1ELVRydXN0JTIwR21iSCxDPURFP2NlcnRpZmljYXRlcmV2b2NhdGlvbmxpc3QwQ6BBoD+G -PWh0dHA6Ly93d3cuZC10cnVzdC5uZXQvY3JsL2QtdHJ1c3Rfcm9vdF9jbGFzc18zX2NhXzJfMjAw -OS5jcmwwDQYJKoZIhvcNAQELBQADggEBAH+X2zDI36ScfSF6gHDOFBJpiBSVYEQBrLLpME+bUMJm -2H6NMLVwMeniacfzcNsgFYbQDfC+rAF1hM5+n02/t2A7nPPKHeJeaNijnZflQGDSNiH+0LS4F9p0 -o3/U37CYAqxva2ssJSRyoWXuJVrl5jLn8t+rSfrzkGkj2wTZ51xY/GXUl77M/C4KzCUqNQT4YJEV -dT1B/yMfGchs64JTBKbkTCJNjYy6zltz7GRUUG3RnFX7acM2w4y8PIWmawomDeCTmGCufsYkl4ph -X5GOZpIJhzbNi5stPvZR1FDUWSi9g/LMKHtThm3YJohw1+qRzT65ysCQblrGXnRl11z+o+I= ------END CERTIFICATE----- - -D-TRUST Root Class 3 CA 2 EV 2009 -================================= ------BEGIN CERTIFICATE----- -MIIEQzCCAyugAwIBAgIDCYP0MA0GCSqGSIb3DQEBCwUAMFAxCzAJBgNVBAYTAkRFMRUwEwYDVQQK -DAxELVRydXN0IEdtYkgxKjAoBgNVBAMMIUQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgRVYgMjAw -OTAeFw0wOTExMDUwODUwNDZaFw0yOTExMDUwODUwNDZaMFAxCzAJBgNVBAYTAkRFMRUwEwYDVQQK -DAxELVRydXN0IEdtYkgxKjAoBgNVBAMMIUQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgRVYgMjAw -OTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJnxhDRwui+3MKCOvXwEz75ivJn9gpfS -egpnljgJ9hBOlSJzmY3aFS3nBfwZcyK3jpgAvDw9rKFs+9Z5JUut8Mxk2og+KbgPCdM03TP1YtHh -zRnp7hhPTFiu4h7WDFsVWtg6uMQYZB7jM7K1iXdODL/ZlGsTl28So/6ZqQTMFexgaDbtCHu39b+T -7WYxg4zGcTSHThfqr4uRjRxWQa4iN1438h3Z0S0NL2lRp75mpoo6Kr3HGrHhFPC+Oh25z1uxav60 -sUYgovseO3Dvk5h9jHOW8sXvhXCtKSb8HgQ+HKDYD8tSg2J87otTlZCpV6LqYQXY+U3EJ/pure35 -11H3a6UCAwEAAaOCASQwggEgMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNOUikxiEyoZLsyv -cop9NteaHNxnMA4GA1UdDwEB/wQEAwIBBjCB3QYDVR0fBIHVMIHSMIGHoIGEoIGBhn9sZGFwOi8v -ZGlyZWN0b3J5LmQtdHJ1c3QubmV0L0NOPUQtVFJVU1QlMjBSb290JTIwQ2xhc3MlMjAzJTIwQ0El -MjAyJTIwRVYlMjAyMDA5LE89RC1UcnVzdCUyMEdtYkgsQz1ERT9jZXJ0aWZpY2F0ZXJldm9jYXRp -b25saXN0MEagRKBChkBodHRwOi8vd3d3LmQtdHJ1c3QubmV0L2NybC9kLXRydXN0X3Jvb3RfY2xh -c3NfM19jYV8yX2V2XzIwMDkuY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQA07XtaPKSUiO8aEXUHL7P+ -PPoeUSbrh/Yp3uDx1MYkCenBz1UbtDDZzhr+BlGmFaQt77JLvyAoJUnRpjZ3NOhk31KxEcdzes05 -nsKtjHEh8lprr988TlWvsoRlFIm5d8sqMb7Po23Pb0iUMkZv53GMoKaEGTcH8gNFCSuGdXzfX2lX -ANtu2KZyIktQ1HWYVt+3GP9DQ1CuekR78HlR10M9p9OB0/DJT7naxpeG0ILD5EJt/rDiZE4OJudA -NCa1CInXCGNjOCd1HjPqbqjdn5lPdE2BiYBL3ZqXKVwvvoFBuYz/6n1gBp7N1z3TLqMVvKjmJuVv -w9y4AyHqnxbxLFS1 ------END CERTIFICATE----- - -CA Disig Root R2 -================ ------BEGIN CERTIFICATE----- -MIIFaTCCA1GgAwIBAgIJAJK4iNuwisFjMA0GCSqGSIb3DQEBCwUAMFIxCzAJBgNVBAYTAlNLMRMw -EQYDVQQHEwpCcmF0aXNsYXZhMRMwEQYDVQQKEwpEaXNpZyBhLnMuMRkwFwYDVQQDExBDQSBEaXNp -ZyBSb290IFIyMB4XDTEyMDcxOTA5MTUzMFoXDTQyMDcxOTA5MTUzMFowUjELMAkGA1UEBhMCU0sx -EzARBgNVBAcTCkJyYXRpc2xhdmExEzARBgNVBAoTCkRpc2lnIGEucy4xGTAXBgNVBAMTEENBIERp -c2lnIFJvb3QgUjIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCio8QACdaFXS1tFPbC -w3OeNcJxVX6B+6tGUODBfEl45qt5WDza/3wcn9iXAng+a0EE6UG9vgMsRfYvZNSrXaNHPWSb6Wia -xswbP7q+sos0Ai6YVRn8jG+qX9pMzk0DIaPY0jSTVpbLTAwAFjxfGs3Ix2ymrdMxp7zo5eFm1tL7 -A7RBZckQrg4FY8aAamkw/dLukO8NJ9+flXP04SXabBbeQTg06ov80egEFGEtQX6sx3dOy1FU+16S -GBsEWmjGycT6txOgmLcRK7fWV8x8nhfRyyX+hk4kLlYMeE2eARKmK6cBZW58Yh2EhN/qwGu1pSqV -g8NTEQxzHQuyRpDRQjrOQG6Vrf/GlK1ul4SOfW+eioANSW1z4nuSHsPzwfPrLgVv2RvPN3YEyLRa -5Beny912H9AZdugsBbPWnDTYltxhh5EF5EQIM8HauQhl1K6yNg3ruji6DOWbnuuNZt2Zz9aJQfYE -koopKW1rOhzndX0CcQ7zwOe9yxndnWCywmZgtrEE7snmhrmaZkCo5xHtgUUDi/ZnWejBBhG93c+A -Ak9lQHhcR1DIm+YfgXvkRKhbhZri3lrVx/k6RGZL5DJUfORsnLMOPReisjQS1n6yqEm70XooQL6i -Fh/f5DcfEXP7kAplQ6INfPgGAVUzfbANuPT1rqVCV3w2EYx7XsQDnYx5nQIDAQABo0IwQDAPBgNV -HRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUtZn4r7CU9eMg1gqtzk5WpC5u -Qu0wDQYJKoZIhvcNAQELBQADggIBACYGXnDnZTPIgm7ZnBc6G3pmsgH2eDtpXi/q/075KMOYKmFM -tCQSin1tERT3nLXK5ryeJ45MGcipvXrA1zYObYVybqjGom32+nNjf7xueQgcnYqfGopTpti72TVV -sRHFqQOzVju5hJMiXn7B9hJSi+osZ7z+Nkz1uM/Rs0mSO9MpDpkblvdhuDvEK7Z4bLQjb/D907Je -dR+Zlais9trhxTF7+9FGs9K8Z7RiVLoJ92Owk6Ka+elSLotgEqv89WBW7xBci8QaQtyDW2QOy7W8 -1k/BfDxujRNt+3vrMNDcTa/F1balTFtxyegxvug4BkihGuLq0t4SOVga/4AOgnXmt8kHbA7v/zjx -mHHEt38OFdAlab0inSvtBfZGR6ztwPDUO+Ls7pZbkBNOHlY667DvlruWIxG68kOGdGSVyCh13x01 -utI3gzhTODY7z2zp+WsO0PsE6E9312UBeIYMej4hYvF/Y3EMyZ9E26gnonW+boE+18DrG5gPcFw0 -sorMwIUY6256s/daoQe/qUKS82Ail+QUoQebTnbAjn39pCXHR+3/H3OszMOl6W8KjptlwlCFtaOg -UxLMVYdh84GuEEZhvUQhuMI9dM9+JDX6HAcOmz0iyu8xL4ysEr3vQCj8KWefshNPZiTEUxnpHikV -7+ZtsH8tZ/3zbBt1RqPlShfppNcL ------END CERTIFICATE----- - -ACCVRAIZ1 -========= ------BEGIN CERTIFICATE----- -MIIH0zCCBbugAwIBAgIIXsO3pkN/pOAwDQYJKoZIhvcNAQEFBQAwQjESMBAGA1UEAwwJQUNDVlJB -SVoxMRAwDgYDVQQLDAdQS0lBQ0NWMQ0wCwYDVQQKDARBQ0NWMQswCQYDVQQGEwJFUzAeFw0xMTA1 -MDUwOTM3MzdaFw0zMDEyMzEwOTM3MzdaMEIxEjAQBgNVBAMMCUFDQ1ZSQUlaMTEQMA4GA1UECwwH -UEtJQUNDVjENMAsGA1UECgwEQUNDVjELMAkGA1UEBhMCRVMwggIiMA0GCSqGSIb3DQEBAQUAA4IC -DwAwggIKAoICAQCbqau/YUqXry+XZpp0X9DZlv3P4uRm7x8fRzPCRKPfmt4ftVTdFXxpNRFvu8gM -jmoYHtiP2Ra8EEg2XPBjs5BaXCQ316PWywlxufEBcoSwfdtNgM3802/J+Nq2DoLSRYWoG2ioPej0 -RGy9ocLLA76MPhMAhN9KSMDjIgro6TenGEyxCQ0jVn8ETdkXhBilyNpAlHPrzg5XPAOBOp0KoVdD -aaxXbXmQeOW1tDvYvEyNKKGno6e6Ak4l0Squ7a4DIrhrIA8wKFSVf+DuzgpmndFALW4ir50awQUZ -0m/A8p/4e7MCQvtQqR0tkw8jq8bBD5L/0KIV9VMJcRz/RROE5iZe+OCIHAr8Fraocwa48GOEAqDG -WuzndN9wrqODJerWx5eHk6fGioozl2A3ED6XPm4pFdahD9GILBKfb6qkxkLrQaLjlUPTAYVtjrs7 -8yM2x/474KElB0iryYl0/wiPgL/AlmXz7uxLaL2diMMxs0Dx6M/2OLuc5NF/1OVYm3z61PMOm3WR -5LpSLhl+0fXNWhn8ugb2+1KoS5kE3fj5tItQo05iifCHJPqDQsGH+tUtKSpacXpkatcnYGMN285J -9Y0fkIkyF/hzQ7jSWpOGYdbhdQrqeWZ2iE9x6wQl1gpaepPluUsXQA+xtrn13k/c4LOsOxFwYIRK -Q26ZIMApcQrAZQIDAQABo4ICyzCCAscwfQYIKwYBBQUHAQEEcTBvMEwGCCsGAQUFBzAChkBodHRw -Oi8vd3d3LmFjY3YuZXMvZmlsZWFkbWluL0FyY2hpdm9zL2NlcnRpZmljYWRvcy9yYWl6YWNjdjEu -Y3J0MB8GCCsGAQUFBzABhhNodHRwOi8vb2NzcC5hY2N2LmVzMB0GA1UdDgQWBBTSh7Tj3zcnk1X2 -VuqB5TbMjB4/vTAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFNKHtOPfNyeTVfZW6oHlNsyM -Hj+9MIIBcwYDVR0gBIIBajCCAWYwggFiBgRVHSAAMIIBWDCCASIGCCsGAQUFBwICMIIBFB6CARAA -QQB1AHQAbwByAGkAZABhAGQAIABkAGUAIABDAGUAcgB0AGkAZgBpAGMAYQBjAGkA8wBuACAAUgBh -AO0AegAgAGQAZQAgAGwAYQAgAEEAQwBDAFYAIAAoAEEAZwBlAG4AYwBpAGEAIABkAGUAIABUAGUA -YwBuAG8AbABvAGcA7QBhACAAeQAgAEMAZQByAHQAaQBmAGkAYwBhAGMAaQDzAG4AIABFAGwAZQBj -AHQAcgDzAG4AaQBjAGEALAAgAEMASQBGACAAUQA0ADYAMAAxADEANQA2AEUAKQAuACAAQwBQAFMA -IABlAG4AIABoAHQAdABwADoALwAvAHcAdwB3AC4AYQBjAGMAdgAuAGUAczAwBggrBgEFBQcCARYk -aHR0cDovL3d3dy5hY2N2LmVzL2xlZ2lzbGFjaW9uX2MuaHRtMFUGA1UdHwROMEwwSqBIoEaGRGh0 -dHA6Ly93d3cuYWNjdi5lcy9maWxlYWRtaW4vQXJjaGl2b3MvY2VydGlmaWNhZG9zL3JhaXphY2N2 -MV9kZXIuY3JsMA4GA1UdDwEB/wQEAwIBBjAXBgNVHREEEDAOgQxhY2N2QGFjY3YuZXMwDQYJKoZI -hvcNAQEFBQADggIBAJcxAp/n/UNnSEQU5CmH7UwoZtCPNdpNYbdKl02125DgBS4OxnnQ8pdpD70E -R9m+27Up2pvZrqmZ1dM8MJP1jaGo/AaNRPTKFpV8M9xii6g3+CfYCS0b78gUJyCpZET/LtZ1qmxN -YEAZSUNUY9rizLpm5U9EelvZaoErQNV/+QEnWCzI7UiRfD+mAM/EKXMRNt6GGT6d7hmKG9Ww7Y49 -nCrADdg9ZuM8Db3VlFzi4qc1GwQA9j9ajepDvV+JHanBsMyZ4k0ACtrJJ1vnE5Bc5PUzolVt3OAJ -TS+xJlsndQAJxGJ3KQhfnlmstn6tn1QwIgPBHnFk/vk4CpYY3QIUrCPLBhwepH2NDd4nQeit2hW3 -sCPdK6jT2iWH7ehVRE2I9DZ+hJp4rPcOVkkO1jMl1oRQQmwgEh0q1b688nCBpHBgvgW1m54ERL5h -I6zppSSMEYCUWqKiuUnSwdzRp+0xESyeGabu4VXhwOrPDYTkF7eifKXeVSUG7szAh1xA2syVP1Xg -Nce4hL60Xc16gwFy7ofmXx2utYXGJt/mwZrpHgJHnyqobalbz+xFd3+YJ5oyXSrjhO7FmGYvliAd -3djDJ9ew+f7Zfc3Qn48LFFhRny+Lwzgt3uiP1o2HpPVWQxaZLPSkVrQ0uGE3ycJYgBugl6H8WY3p -EfbRD0tVNEYqi4Y7 ------END CERTIFICATE----- - -TWCA Global Root CA -=================== ------BEGIN CERTIFICATE----- -MIIFQTCCAymgAwIBAgICDL4wDQYJKoZIhvcNAQELBQAwUTELMAkGA1UEBhMCVFcxEjAQBgNVBAoT -CVRBSVdBTi1DQTEQMA4GA1UECxMHUm9vdCBDQTEcMBoGA1UEAxMTVFdDQSBHbG9iYWwgUm9vdCBD -QTAeFw0xMjA2MjcwNjI4MzNaFw0zMDEyMzExNTU5NTlaMFExCzAJBgNVBAYTAlRXMRIwEAYDVQQK -EwlUQUlXQU4tQ0ExEDAOBgNVBAsTB1Jvb3QgQ0ExHDAaBgNVBAMTE1RXQ0EgR2xvYmFsIFJvb3Qg -Q0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCwBdvI64zEbooh745NnHEKH1Jw7W2C -nJfF10xORUnLQEK1EjRsGcJ0pDFfhQKX7EMzClPSnIyOt7h52yvVavKOZsTuKwEHktSz0ALfUPZV -r2YOy+BHYC8rMjk1Ujoog/h7FsYYuGLWRyWRzvAZEk2tY/XTP3VfKfChMBwqoJimFb3u/Rk28OKR -Q4/6ytYQJ0lM793B8YVwm8rqqFpD/G2Gb3PpN0Wp8DbHzIh1HrtsBv+baz4X7GGqcXzGHaL3SekV -tTzWoWH1EfcFbx39Eb7QMAfCKbAJTibc46KokWofwpFFiFzlmLhxpRUZyXx1EcxwdE8tmx2RRP1W -KKD+u4ZqyPpcC1jcxkt2yKsi2XMPpfRaAok/T54igu6idFMqPVMnaR1sjjIsZAAmY2E2TqNGtz99 -sy2sbZCilaLOz9qC5wc0GZbpuCGqKX6mOL6OKUohZnkfs8O1CWfe1tQHRvMq2uYiN2DLgbYPoA/p -yJV/v1WRBXrPPRXAb94JlAGD1zQbzECl8LibZ9WYkTunhHiVJqRaCPgrdLQABDzfuBSO6N+pjWxn -kjMdwLfS7JLIvgm/LCkFbwJrnu+8vyq8W8BQj0FwcYeyTbcEqYSjMq+u7msXi7Kx/mzhkIyIqJdI -zshNy/MGz19qCkKxHh53L46g5pIOBvwFItIm4TFRfTLcDwIDAQABoyMwITAOBgNVHQ8BAf8EBAMC -AQYwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAgEAXzSBdu+WHdXltdkCY4QWwa6g -cFGn90xHNcgL1yg9iXHZqjNB6hQbbCEAwGxCGX6faVsgQt+i0trEfJdLjbDorMjupWkEmQqSpqsn -LhpNgb+E1HAerUf+/UqdM+DyucRFCCEK2mlpc3INvjT+lIutwx4116KD7+U4x6WFH6vPNOw/KP4M -8VeGTslV9xzU2KV9Bnpv1d8Q34FOIWWxtuEXeZVFBs5fzNxGiWNoRI2T9GRwoD2dKAXDOXC4Ynsg -/eTb6QihuJ49CcdP+yz4k3ZB3lLg4VfSnQO8d57+nile98FRYB/e2guyLXW3Q0iT5/Z5xoRdgFlg -lPx4mI88k1HtQJAH32RjJMtOcQWh15QaiDLxInQirqWm2BJpTGCjAu4r7NRjkgtevi92a6O2JryP -A9gK8kxkRr05YuWW6zRjESjMlfGt7+/cgFhI6Uu46mWs6fyAtbXIRfmswZ/ZuepiiI7E8UuDEq3m -i4TWnsLrgxifarsbJGAzcMzs9zLzXNl5fe+epP7JI8Mk7hWSsT2RTyaGvWZzJBPqpK5jwa19hAM8 -EHiGG3njxPPyBJUgriOCxLM6AGK/5jYk4Ve6xx6QddVfP5VhK8E7zeWzaGHQRiapIVJpLesux+t3 -zqY6tQMzT3bR51xUAV3LePTJDL/PEo4XLSNolOer/qmyKwbQBM0= ------END CERTIFICATE----- - -TeliaSonera Root CA v1 -====================== ------BEGIN CERTIFICATE----- -MIIFODCCAyCgAwIBAgIRAJW+FqD3LkbxezmCcvqLzZYwDQYJKoZIhvcNAQEFBQAwNzEUMBIGA1UE -CgwLVGVsaWFTb25lcmExHzAdBgNVBAMMFlRlbGlhU29uZXJhIFJvb3QgQ0EgdjEwHhcNMDcxMDE4 -MTIwMDUwWhcNMzIxMDE4MTIwMDUwWjA3MRQwEgYDVQQKDAtUZWxpYVNvbmVyYTEfMB0GA1UEAwwW -VGVsaWFTb25lcmEgUm9vdCBDQSB2MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMK+ -6yfwIaPzaSZVfp3FVRaRXP3vIb9TgHot0pGMYzHw7CTww6XScnwQbfQ3t+XmfHnqjLWCi65ItqwA -3GV17CpNX8GH9SBlK4GoRz6JI5UwFpB/6FcHSOcZrr9FZ7E3GwYq/t75rH2D+1665I+XZ75Ljo1k -B1c4VWk0Nj0TSO9P4tNmHqTPGrdeNjPUtAa9GAH9d4RQAEX1jF3oI7x+/jXh7VB7qTCNGdMJjmhn -Xb88lxhTuylixcpecsHHltTbLaC0H2kD7OriUPEMPPCs81Mt8Bz17Ww5OXOAFshSsCPN4D7c3TxH -oLs1iuKYaIu+5b9y7tL6pe0S7fyYGKkmdtwoSxAgHNN/Fnct7W+A90m7UwW7XWjH1Mh1Fj+JWov3 -F0fUTPHSiXk+TT2YqGHeOh7S+F4D4MHJHIzTjU3TlTazN19jY5szFPAtJmtTfImMMsJu7D0hADnJ -oWjiUIMusDor8zagrC/kb2HCUQk5PotTubtn2txTuXZZNp1D5SDgPTJghSJRt8czu90VL6R4pgd7 -gUY2BIbdeTXHlSw7sKMXNeVzH7RcWe/a6hBle3rQf5+ztCo3O3CLm1u5K7fsslESl1MpWtTwEhDc -TwK7EpIvYtQ/aUN8Ddb8WHUBiJ1YFkveupD/RwGJBmr2X7KQarMCpgKIv7NHfirZ1fpoeDVNAgMB -AAGjPzA9MA8GA1UdEwEB/wQFMAMBAf8wCwYDVR0PBAQDAgEGMB0GA1UdDgQWBBTwj1k4ALP1j5qW -DNXr+nuqF+gTEjANBgkqhkiG9w0BAQUFAAOCAgEAvuRcYk4k9AwI//DTDGjkk0kiP0Qnb7tt3oNm -zqjMDfz1mgbldxSR651Be5kqhOX//CHBXfDkH1e3damhXwIm/9fH907eT/j3HEbAek9ALCI18Bmx -0GtnLLCo4MBANzX2hFxc469CeP6nyQ1Q6g2EdvZR74NTxnr/DlZJLo961gzmJ1TjTQpgcmLNkQfW -pb/ImWvtxBnmq0wROMVvMeJuScg/doAmAyYp4Db29iBT4xdwNBedY2gea+zDTYa4EzAvXUYNR0PV -G6pZDrlcjQZIrXSHX8f8MVRBE+LHIQ6e4B4N4cB7Q4WQxYpYxmUKeFfyxiMPAdkgS94P+5KFdSpc -c41teyWRyu5FrgZLAMzTsVlQ2jqIOylDRl6XK1TOU2+NSueW+r9xDkKLfP0ooNBIytrEgUy7onOT -JsjrDNYmiLbAJM+7vVvrdX3pCI6GMyx5dwlppYn8s3CQh3aP0yK7Qs69cwsgJirQmz1wHiRszYd2 -qReWt88NkvuOGKmYSdGe/mBEciG5Ge3C9THxOUiIkCR1VBatzvT4aRRkOfujuLpwQMcnHL/EVlP6 -Y2XQ8xwOFvVrhlhNGNTkDY6lnVuR3HYkUD/GKvvZt5y11ubQ2egZixVxSK236thZiNSQvxaz2ems -WWFUyBy6ysHK4bkgTI86k4mloMy/0/Z1pHWWbVY= ------END CERTIFICATE----- - -T-TeleSec GlobalRoot Class 2 -============================ ------BEGIN CERTIFICATE----- -MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoM -IlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBU -cnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDIwHhcNMDgx -MDAxMTA0MDE0WhcNMzMxMDAxMjM1OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lz -dGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBD -ZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDIwggEiMA0GCSqGSIb3 -DQEBAQUAA4IBDwAwggEKAoIBAQCqX9obX+hzkeXaXPSi5kfl82hVYAUdAqSzm1nzHoqvNK38DcLZ -SBnuaY/JIPwhqgcZ7bBcrGXHX+0CfHt8LRvWurmAwhiCFoT6ZrAIxlQjgeTNuUk/9k9uN0goOA/F -vudocP05l03Sx5iRUKrERLMjfTlH6VJi1hKTXrcxlkIF+3anHqP1wvzpesVsqXFP6st4vGCvx970 -2cu+fjOlbpSD8DT6IavqjnKgP6TeMFvvhk1qlVtDRKgQFRzlAVfFmPHmBiiRqiDFt1MmUUOyCxGV -WOHAD3bZwI18gfNycJ5v/hqO2V81xrJvNHy+SE/iWjnX2J14np+GPgNeGYtEotXHAgMBAAGjQjBA -MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS/WSA2AHmgoCJrjNXy -YdK4LMuCSjANBgkqhkiG9w0BAQsFAAOCAQEAMQOiYQsfdOhyNsZt+U2e+iKo4YFWz827n+qrkRk4 -r6p8FU3ztqONpfSO9kSpp+ghla0+AGIWiPACuvxhI+YzmzB6azZie60EI4RYZeLbK4rnJVM3YlNf -vNoBYimipidx5joifsFvHZVwIEoHNN/q/xWA5brXethbdXwFeilHfkCoMRN3zUA7tFFHei4R40cR -3p1m0IvVVGb6g1XqfMIpiRvpb7PO4gWEyS8+eIVibslfwXhjdFjASBgMmTnrpMwatXlajRWc2BQN -9noHV8cigwUtPJslJj0Ys6lDfMjIq2SPDqO/nBudMNva0Bkuqjzx+zOAduTNrRlPBSeOE6Fuwg== ------END CERTIFICATE----- - -Atos TrustedRoot 2011 -===================== ------BEGIN CERTIFICATE----- -MIIDdzCCAl+gAwIBAgIIXDPLYixfszIwDQYJKoZIhvcNAQELBQAwPDEeMBwGA1UEAwwVQXRvcyBU -cnVzdGVkUm9vdCAyMDExMQ0wCwYDVQQKDARBdG9zMQswCQYDVQQGEwJERTAeFw0xMTA3MDcxNDU4 -MzBaFw0zMDEyMzEyMzU5NTlaMDwxHjAcBgNVBAMMFUF0b3MgVHJ1c3RlZFJvb3QgMjAxMTENMAsG -A1UECgwEQXRvczELMAkGA1UEBhMCREUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCV -hTuXbyo7LjvPpvMpNb7PGKw+qtn4TaA+Gke5vJrf8v7MPkfoepbCJI419KkM/IL9bcFyYie96mvr -54rMVD6QUM+A1JX76LWC1BTFtqlVJVfbsVD2sGBkWXppzwO3bw2+yj5vdHLqqjAqc2K+SZFhyBH+ -DgMq92og3AIVDV4VavzjgsG1xZ1kCWyjWZgHJ8cblithdHFsQ/H3NYkQ4J7sVaE3IqKHBAUsR320 -HLliKWYoyrfhk/WklAOZuXCFteZI6o1Q/NnezG8HDt0Lcp2AMBYHlT8oDv3FdU9T1nSatCQujgKR -z3bFmx5VdJx4IbHwLfELn8LVlhgf8FQieowHAgMBAAGjfTB7MB0GA1UdDgQWBBSnpQaxLKYJYO7R -l+lwrrw7GWzbITAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFKelBrEspglg7tGX6XCuvDsZ -bNshMBgGA1UdIAQRMA8wDQYLKwYBBAGwLQMEAQEwDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEB -CwUAA4IBAQAmdzTblEiGKkGdLD4GkGDEjKwLVLgfuXvTBznk+j57sj1O7Z8jvZfza1zv7v1Apt+h -k6EKhqzvINB5Ab149xnYJDE0BAGmuhWawyfc2E8PzBhj/5kPDpFrdRbhIfzYJsdHt6bPWHJxfrrh -TZVHO8mvbaG0weyJ9rQPOLXiZNwlz6bb65pcmaHFCN795trV1lpFDMS3wrUU77QR/w4VtfX128a9 -61qn8FYiqTxlVMYVqL2Gns2Dlmh6cYGJ4Qvh6hEbaAjMaZ7snkGeRDImeuKHCnE96+RapNLbxc3G -3mB/ufNPRJLvKrcYPqcZ2Qt9sTdBQrC6YB3y/gkRsPCHe6ed ------END CERTIFICATE----- - -QuoVadis Root CA 1 G3 -===================== ------BEGIN CERTIFICATE----- -MIIFYDCCA0igAwIBAgIUeFhfLq0sGUvjNwc1NBMotZbUZZMwDQYJKoZIhvcNAQELBQAwSDELMAkG -A1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAcBgNVBAMTFVF1b1ZhZGlzIFJv -b3QgQ0EgMSBHMzAeFw0xMjAxMTIxNzI3NDRaFw00MjAxMTIxNzI3NDRaMEgxCzAJBgNVBAYTAkJN -MRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDEg -RzMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCgvlAQjunybEC0BJyFuTHK3C3kEakE -PBtVwedYMB0ktMPvhd6MLOHBPd+C5k+tR4ds7FtJwUrVu4/sh6x/gpqG7D0DmVIB0jWerNrwU8lm -PNSsAgHaJNM7qAJGr6Qc4/hzWHa39g6QDbXwz8z6+cZM5cOGMAqNF34168Xfuw6cwI2H44g4hWf6 -Pser4BOcBRiYz5P1sZK0/CPTz9XEJ0ngnjybCKOLXSoh4Pw5qlPafX7PGglTvF0FBM+hSo+LdoIN -ofjSxxR3W5A2B4GbPgb6Ul5jxaYA/qXpUhtStZI5cgMJYr2wYBZupt0lwgNm3fME0UDiTouG9G/l -g6AnhF4EwfWQvTA9xO+oabw4m6SkltFi2mnAAZauy8RRNOoMqv8hjlmPSlzkYZqn0ukqeI1RPToV -7qJZjqlc3sX5kCLliEVx3ZGZbHqfPT2YfF72vhZooF6uCyP8Wg+qInYtyaEQHeTTRCOQiJ/GKubX -9ZqzWB4vMIkIG1SitZgj7Ah3HJVdYdHLiZxfokqRmu8hqkkWCKi9YSgxyXSthfbZxbGL0eUQMk1f -iyA6PEkfM4VZDdvLCXVDaXP7a3F98N/ETH3Goy7IlXnLc6KOTk0k+17kBL5yG6YnLUlamXrXXAkg -t3+UuU/xDRxeiEIbEbfnkduebPRq34wGmAOtzCjvpUfzUwIDAQABo0IwQDAPBgNVHRMBAf8EBTAD -AQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUo5fW816iEOGrRZ88F2Q87gFwnMwwDQYJKoZI -hvcNAQELBQADggIBABj6W3X8PnrHX3fHyt/PX8MSxEBd1DKquGrX1RUVRpgjpeaQWxiZTOOtQqOC -MTaIzen7xASWSIsBx40Bz1szBpZGZnQdT+3Btrm0DWHMY37XLneMlhwqI2hrhVd2cDMT/uFPpiN3 -GPoajOi9ZcnPP/TJF9zrx7zABC4tRi9pZsMbj/7sPtPKlL92CiUNqXsCHKnQO18LwIE6PWThv6ct -Tr1NxNgpxiIY0MWscgKCP6o6ojoilzHdCGPDdRS5YCgtW2jgFqlmgiNR9etT2DGbe+m3nUvriBbP -+V04ikkwj+3x6xn0dxoxGE1nVGwvb2X52z3sIexe9PSLymBlVNFxZPT5pqOBMzYzcfCkeF9OrYMh -3jRJjehZrJ3ydlo28hP0r+AJx2EqbPfgna67hkooby7utHnNkDPDs3b69fBsnQGQ+p6Q9pxyz0fa -wx/kNSBT8lTR32GDpgLiJTjehTItXnOQUl1CxM49S+H5GYQd1aJQzEH7QRTDvdbJWqNjZgKAvQU6 -O0ec7AAmTPWIUb+oI38YB7AL7YsmoWTTYUrrXJ/es69nA7Mf3W1daWhpq1467HxpvMc7hU6eFbm0 -FU/DlXpY18ls6Wy58yljXrQs8C097Vpl4KlbQMJImYFtnh8GKjwStIsPm6Ik8KaN1nrgS7ZklmOV -hMJKzRwuJIczYOXD ------END CERTIFICATE----- - -QuoVadis Root CA 2 G3 -===================== ------BEGIN CERTIFICATE----- -MIIFYDCCA0igAwIBAgIURFc0JFuBiZs18s64KztbpybwdSgwDQYJKoZIhvcNAQELBQAwSDELMAkG -A1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAcBgNVBAMTFVF1b1ZhZGlzIFJv -b3QgQ0EgMiBHMzAeFw0xMjAxMTIxODU5MzJaFw00MjAxMTIxODU5MzJaMEgxCzAJBgNVBAYTAkJN -MRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDIg -RzMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQChriWyARjcV4g/Ruv5r+LrI3HimtFh -ZiFfqq8nUeVuGxbULX1QsFN3vXg6YOJkApt8hpvWGo6t/x8Vf9WVHhLL5hSEBMHfNrMWn4rjyduY -NM7YMxcoRvynyfDStNVNCXJJ+fKH46nafaF9a7I6JaltUkSs+L5u+9ymc5GQYaYDFCDy54ejiK2t -oIz/pgslUiXnFgHVy7g1gQyjO/Dh4fxaXc6AcW34Sas+O7q414AB+6XrW7PFXmAqMaCvN+ggOp+o -MiwMzAkd056OXbxMmO7FGmh77FOm6RQ1o9/NgJ8MSPsc9PG/Srj61YxxSscfrf5BmrODXfKEVu+l -V0POKa2Mq1W/xPtbAd0jIaFYAI7D0GoT7RPjEiuA3GfmlbLNHiJuKvhB1PLKFAeNilUSxmn1uIZo -L1NesNKqIcGY5jDjZ1XHm26sGahVpkUG0CM62+tlXSoREfA7T8pt9DTEceT/AFr2XK4jYIVz8eQQ -sSWu1ZK7E8EM4DnatDlXtas1qnIhO4M15zHfeiFuuDIIfR0ykRVKYnLP43ehvNURG3YBZwjgQQvD -6xVu+KQZ2aKrr+InUlYrAoosFCT5v0ICvybIxo/gbjh9Uy3l7ZizlWNof/k19N+IxWA1ksB8aRxh -lRbQ694Lrz4EEEVlWFA4r0jyWbYW8jwNkALGcC4BrTwV1wIDAQABo0IwQDAPBgNVHRMBAf8EBTAD -AQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQU7edvdlq/YOxJW8ald7tyFnGbxD0wDQYJKoZI -hvcNAQELBQADggIBAJHfgD9DCX5xwvfrs4iP4VGyvD11+ShdyLyZm3tdquXK4Qr36LLTn91nMX66 -AarHakE7kNQIXLJgapDwyM4DYvmL7ftuKtwGTTwpD4kWilhMSA/ohGHqPHKmd+RCroijQ1h5fq7K -pVMNqT1wvSAZYaRsOPxDMuHBR//47PERIjKWnML2W2mWeyAMQ0GaW/ZZGYjeVYg3UQt4XAoeo0L9 -x52ID8DyeAIkVJOviYeIyUqAHerQbj5hLja7NQ4nlv1mNDthcnPxFlxHBlRJAHpYErAK74X9sbgz -dWqTHBLmYF5vHX/JHyPLhGGfHoJE+V+tYlUkmlKY7VHnoX6XOuYvHxHaU4AshZ6rNRDbIl9qxV6X -U/IyAgkwo1jwDQHVcsaxfGl7w/U2Rcxhbl5MlMVerugOXou/983g7aEOGzPuVBj+D77vfoRrQ+Nw -mNtddbINWQeFFSM51vHfqSYP1kjHs6Yi9TM3WpVHn3u6GBVv/9YUZINJ0gpnIdsPNWNgKCLjsZWD -zYWm3S8P52dSbrsvhXz1SnPnxT7AvSESBT/8twNJAlvIJebiVDj1eYeMHVOyToV7BjjHLPj4sHKN -JeV3UvQDHEimUF+IIDBu8oJDqz2XhOdT+yHBTw8imoa4WSr2Rz0ZiC3oheGe7IUIarFsNMkd7Egr -O3jtZsSOeWmD3n+M ------END CERTIFICATE----- - -QuoVadis Root CA 3 G3 -===================== ------BEGIN CERTIFICATE----- -MIIFYDCCA0igAwIBAgIULvWbAiin23r/1aOp7r0DoM8Sah0wDQYJKoZIhvcNAQELBQAwSDELMAkG -A1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAcBgNVBAMTFVF1b1ZhZGlzIFJv -b3QgQ0EgMyBHMzAeFw0xMjAxMTIyMDI2MzJaFw00MjAxMTIyMDI2MzJaMEgxCzAJBgNVBAYTAkJN -MRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDMg -RzMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCzyw4QZ47qFJenMioKVjZ/aEzHs286 -IxSR/xl/pcqs7rN2nXrpixurazHb+gtTTK/FpRp5PIpM/6zfJd5O2YIyC0TeytuMrKNuFoM7pmRL -Mon7FhY4futD4tN0SsJiCnMK3UmzV9KwCoWdcTzeo8vAMvMBOSBDGzXRU7Ox7sWTaYI+FrUoRqHe -6okJ7UO4BUaKhvVZR74bbwEhELn9qdIoyhA5CcoTNs+cra1AdHkrAj80//ogaX3T7mH1urPnMNA3 -I4ZyYUUpSFlob3emLoG+B01vr87ERRORFHAGjx+f+IdpsQ7vw4kZ6+ocYfx6bIrc1gMLnia6Et3U -VDmrJqMz6nWB2i3ND0/kA9HvFZcba5DFApCTZgIhsUfei5pKgLlVj7WiL8DWM2fafsSntARE60f7 -5li59wzweyuxwHApw0BiLTtIadwjPEjrewl5qW3aqDCYz4ByA4imW0aucnl8CAMhZa634RylsSqi -Md5mBPfAdOhx3v89WcyWJhKLhZVXGqtrdQtEPREoPHtht+KPZ0/l7DxMYIBpVzgeAVuNVejH38DM -dyM0SXV89pgR6y3e7UEuFAUCf+D+IOs15xGsIs5XPd7JMG0QA4XN8f+MFrXBsj6IbGB/kE+V9/Yt -rQE5BwT6dYB9v0lQ7e/JxHwc64B+27bQ3RP+ydOc17KXqQIDAQABo0IwQDAPBgNVHRMBAf8EBTAD -AQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUxhfQvKjqAkPyGwaZXSuQILnXnOQwDQYJKoZI -hvcNAQELBQADggIBADRh2Va1EodVTd2jNTFGu6QHcrxfYWLopfsLN7E8trP6KZ1/AvWkyaiTt3px -KGmPc+FSkNrVvjrlt3ZqVoAh313m6Tqe5T72omnHKgqwGEfcIHB9UqM+WXzBusnIFUBhynLWcKzS -t/Ac5IYp8M7vaGPQtSCKFWGafoaYtMnCdvvMujAWzKNhxnQT5WvvoxXqA/4Ti2Tk08HS6IT7SdEQ -TXlm66r99I0xHnAUrdzeZxNMgRVhvLfZkXdxGYFgu/BYpbWcC/ePIlUnwEsBbTuZDdQdm2NnL9Du -DcpmvJRPpq3t/O5jrFc/ZSXPsoaP0Aj/uHYUbt7lJ+yreLVTubY/6CD50qi+YUbKh4yE8/nxoGib -Ih6BJpsQBJFxwAYf3KDTuVan45gtf4Od34wrnDKOMpTwATwiKp9Dwi7DmDkHOHv8XgBCH/MyJnmD -hPbl8MFREsALHgQjDFSlTC9JxUrRtm5gDWv8a4uFJGS3iQ6rJUdbPM9+Sb3H6QrG2vd+DhcI00iX -0HGS8A85PjRqHH3Y8iKuu2n0M7SmSFXRDw4m6Oy2Cy2nhTXN/VnIn9HNPlopNLk9hM6xZdRZkZFW -dSHBd575euFgndOtBBj0fOtek49TSiIp+EgrPk2GrFt/ywaZWWDYWGWVjUTR939+J399roD1B0y2 -PpxxVJkES/1Y+Zj0 ------END CERTIFICATE----- - -DigiCert Assured ID Root G2 -=========================== ------BEGIN CERTIFICATE----- -MIIDljCCAn6gAwIBAgIQC5McOtY5Z+pnI7/Dr5r0SzANBgkqhkiG9w0BAQsFADBlMQswCQYDVQQG -EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSQw -IgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzIwHhcNMTMwODAxMTIwMDAwWhcNMzgw -MTE1MTIwMDAwWjBlMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQL -ExB3d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzIw -ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDZ5ygvUj82ckmIkzTz+GoeMVSAn61UQbVH -35ao1K+ALbkKz3X9iaV9JPrjIgwrvJUXCzO/GU1BBpAAvQxNEP4HteccbiJVMWWXvdMX0h5i89vq -bFCMP4QMls+3ywPgym2hFEwbid3tALBSfK+RbLE4E9HpEgjAALAcKxHad3A2m67OeYfcgnDmCXRw -VWmvo2ifv922ebPynXApVfSr/5Vh88lAbx3RvpO704gqu52/clpWcTs/1PPRCv4o76Pu2ZmvA9OP -YLfykqGxvYmJHzDNw6YuYjOuFgJ3RFrngQo8p0Quebg/BLxcoIfhG69Rjs3sLPr4/m3wOnyqi+Rn -lTGNAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBTO -w0q5mVXyuNtgv6l+vVa1lzan1jANBgkqhkiG9w0BAQsFAAOCAQEAyqVVjOPIQW5pJ6d1Ee88hjZv -0p3GeDgdaZaikmkuOGybfQTUiaWxMTeKySHMq2zNixya1r9I0jJmwYrA8y8678Dj1JGG0VDjA9tz -d29KOVPt3ibHtX2vK0LRdWLjSisCx1BL4GnilmwORGYQRI+tBev4eaymG+g3NJ1TyWGqolKvSnAW -hsI6yLETcDbYz+70CjTVW0z9B5yiutkBclzzTcHdDrEcDcRjvq30FPuJ7KJBDkzMyFdA0G4Dqs0M -jomZmWzwPDCvON9vvKO+KSAnq3T/EyJ43pdSVR6DtVQgA+6uwE9W3jfMw3+qBCe703e4YtsXfJwo -IhNzbM8m9Yop5w== ------END CERTIFICATE----- - -DigiCert Assured ID Root G3 -=========================== ------BEGIN CERTIFICATE----- -MIICRjCCAc2gAwIBAgIQC6Fa+h3foLVJRK/NJKBs7DAKBggqhkjOPQQDAzBlMQswCQYDVQQGEwJV -UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSQwIgYD -VQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzMwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1 -MTIwMDAwWjBlMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 -d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzMwdjAQ -BgcqhkjOPQIBBgUrgQQAIgNiAAQZ57ysRGXtzbg/WPuNsVepRC0FFfLvC/8QdJ+1YlJfZn4f5dwb -RXkLzMZTCp2NXQLZqVneAlr2lSoOjThKiknGvMYDOAdfVdp+CW7if17QRSAPWXYQ1qAk8C3eNvJs -KTmjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBTL0L2p4ZgF -UaFNN6KDec6NHSrkhDAKBggqhkjOPQQDAwNnADBkAjAlpIFFAmsSS3V0T8gj43DydXLefInwz5Fy -YZ5eEJJZVrmDxxDnOOlYJjZ91eQ0hjkCMHw2U/Aw5WJjOpnitqM7mzT6HtoQknFekROn3aRukswy -1vUhZscv6pZjamVFkpUBtA== ------END CERTIFICATE----- - -DigiCert Global Root G2 -======================= ------BEGIN CERTIFICATE----- -MIIDjjCCAnagAwIBAgIQAzrx5qcRqaC7KGSxHQn65TANBgkqhkiG9w0BAQsFADBhMQswCQYDVQQG -EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSAw -HgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBHMjAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUx -MjAwMDBaMGExCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3 -dy5kaWdpY2VydC5jb20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEcyMIIBIjANBgkq -hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzfNNNx7a8myaJCtSnX/RrohCgiN9RlUyfuI2/Ou8jqJ -kTx65qsGGmvPrC3oXgkkRLpimn7Wo6h+4FR1IAWsULecYxpsMNzaHxmx1x7e/dfgy5SDN67sH0NO -3Xss0r0upS/kqbitOtSZpLYl6ZtrAGCSYP9PIUkY92eQq2EGnI/yuum06ZIya7XzV+hdG82MHauV -BJVJ8zUtluNJbd134/tJS7SsVQepj5WztCO7TG1F8PapspUwtP1MVYwnSlcUfIKdzXOS0xZKBgyM -UNGPHgm+F6HmIcr9g+UQvIOlCsRnKPZzFBQ9RnbDhxSJITRNrw9FDKZJobq7nMWxM4MphQIDAQAB -o0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUTiJUIBiV5uNu -5g/6+rkS7QYXjzkwDQYJKoZIhvcNAQELBQADggEBAGBnKJRvDkhj6zHd6mcY1Yl9PMWLSn/pvtsr -F9+wX3N3KjITOYFnQoQj8kVnNeyIv/iPsGEMNKSuIEyExtv4NeF22d+mQrvHRAiGfzZ0JFrabA0U -WTW98kndth/Jsw1HKj2ZL7tcu7XUIOGZX1NGFdtom/DzMNU+MeKNhJ7jitralj41E6Vf8PlwUHBH -QRFXGU7Aj64GxJUTFy8bJZ918rGOmaFvE7FBcf6IKshPECBV1/MUReXgRPTqh5Uykw7+U0b6LJ3/ -iyK5S9kJRaTepLiaWN0bfVKfjllDiIGknibVb63dDcY3fe0Dkhvld1927jyNxF1WW6LZZm6zNTfl -MrY= ------END CERTIFICATE----- - -DigiCert Global Root G3 -======================= ------BEGIN CERTIFICATE----- -MIICPzCCAcWgAwIBAgIQBVVWvPJepDU1w6QP1atFcjAKBggqhkjOPQQDAzBhMQswCQYDVQQGEwJV -UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSAwHgYD -VQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBHMzAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAw -MDBaMGExCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5k -aWdpY2VydC5jb20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEczMHYwEAYHKoZIzj0C -AQYFK4EEACIDYgAE3afZu4q4C/sLfyHS8L6+c/MzXRq8NOrexpu80JX28MzQC7phW1FGfp4tn+6O -YwwX7Adw9c+ELkCDnOg/QW07rdOkFFk2eJ0DQ+4QE2xy3q6Ip6FrtUPOZ9wj/wMco+I+o0IwQDAP -BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUs9tIpPmhxdiuNkHMEWNp -Yim8S8YwCgYIKoZIzj0EAwMDaAAwZQIxAK288mw/EkrRLTnDCgmXc/SINoyIJ7vmiI1Qhadj+Z4y -3maTD/HMsQmP3Wyr+mt/oAIwOWZbwmSNuJ5Q3KjVSaLtx9zRSX8XAbjIho9OjIgrqJqpisXRAL34 -VOKa5Vt8sycX ------END CERTIFICATE----- - -DigiCert Trusted Root G4 -======================== ------BEGIN CERTIFICATE----- -MIIFkDCCA3igAwIBAgIQBZsbV56OITLiOQe9p3d1XDANBgkqhkiG9w0BAQwFADBiMQswCQYDVQQG -EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSEw -HwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1 -MTIwMDAwWjBiMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 -d3cuZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwggIiMA0G -CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC/5pBzaN675F1KPDAiMGkz7MKnJS7JIT3yithZwuEp -pz1Yq3aaza57G4QNxDAf8xukOBbrVsaXbR2rsnnyyhHS5F/WBTxSD1Ifxp4VpX6+n6lXFllVcq9o -k3DCsrp1mWpzMpTREEQQLt+C8weE5nQ7bXHiLQwb7iDVySAdYyktzuxeTsiT+CFhmzTrBcZe7Fsa -vOvJz82sNEBfsXpm7nfISKhmV1efVFiODCu3T6cw2Vbuyntd463JT17lNecxy9qTXtyOj4DatpGY -QJB5w3jHtrHEtWoYOAMQjdjUN6QuBX2I9YI+EJFwq1WCQTLX2wRzKm6RAXwhTNS8rhsDdV14Ztk6 -MUSaM0C/CNdaSaTC5qmgZ92kJ7yhTzm1EVgX9yRcRo9k98FpiHaYdj1ZXUJ2h4mXaXpI8OCiEhtm -mnTK3kse5w5jrubU75KSOp493ADkRSWJtppEGSt+wJS00mFt6zPZxd9LBADMfRyVw4/3IbKyEbe7 -f/LVjHAsQWCqsWMYRJUadmJ+9oCw++hkpjPRiQfhvbfmQ6QYuKZ3AeEPlAwhHbJUKSWJbOUOUlFH -dL4mrLZBdd56rF+NP8m800ERElvlEFDrMcXKchYiCd98THU/Y+whX8QgUWtvsauGi0/C1kVfnSD8 -oR7FwI+isX4KJpn15GkvmB0t9dmpsh3lGwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1Ud -DwEB/wQEAwIBhjAdBgNVHQ4EFgQU7NfjgtJxXWRM3y5nP+e6mK4cD08wDQYJKoZIhvcNAQEMBQAD -ggIBALth2X2pbL4XxJEbw6GiAI3jZGgPVs93rnD5/ZpKmbnJeFwMDF/k5hQpVgs2SV1EY+CtnJYY -ZhsjDT156W1r1lT40jzBQ0CuHVD1UvyQO7uYmWlrx8GnqGikJ9yd+SeuMIW59mdNOj6PWTkiU0Tr -yF0Dyu1Qen1iIQqAyHNm0aAFYF/opbSnr6j3bTWcfFqK1qI4mfN4i/RN0iAL3gTujJtHgXINwBQy -7zBZLq7gcfJW5GqXb5JQbZaNaHqasjYUegbyJLkJEVDXCLG4iXqEI2FCKeWjzaIgQdfRnGTZ6iah -ixTXTBmyUEFxPT9NcCOGDErcgdLMMpSEDQgJlxxPwO5rIHQw0uA5NBCFIRUBCOhVMt5xSdkoF1BN -5r5N0XWs0Mr7QbhDparTwwVETyw2m+L64kW4I1NsBm9nVX9GtUw/bihaeSbSpKhil9Ie4u1Ki7wb -/UdKDd9nZn6yW0HQO+T0O/QEY+nvwlQAUaCKKsnOeMzV6ocEGLPOr0mIr/OSmbaz5mEP0oUA51Aa -5BuVnRmhuZyxm7EAHu/QD09CbMkKvO5D+jpxpchNJqU1/YldvIViHTLSoCtU7ZpXwdv6EM8Zt4tK -G48BtieVU+i2iW1bvGjUI+iLUaJW+fCmgKDWHrO8Dw9TdSmq6hN35N6MgSGtBxBHEa2HPQfRdbzP -82Z+ ------END CERTIFICATE----- - -COMODO RSA Certification Authority -================================== ------BEGIN CERTIFICATE----- -MIIF2DCCA8CgAwIBAgIQTKr5yttjb+Af907YWwOGnTANBgkqhkiG9w0BAQwFADCBhTELMAkGA1UE -BhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgG -A1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNhdGlv -biBBdXRob3JpdHkwHhcNMTAwMTE5MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMC -R0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UE -ChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNhdGlvbiBB -dXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCR6FSS0gpWsawNJN3Fz0Rn -dJkrN6N9I3AAcbxT38T6KhKPS38QVr2fcHK3YX/JSw8Xpz3jsARh7v8Rl8f0hj4K+j5c+ZPmNHrZ -FGvnnLOFoIJ6dq9xkNfs/Q36nGz637CC9BR++b7Epi9Pf5l/tfxnQ3K9DADWietrLNPtj5gcFKt+ -5eNu/Nio5JIk2kNrYrhV/erBvGy2i/MOjZrkm2xpmfh4SDBF1a3hDTxFYPwyllEnvGfDyi62a+pG -x8cgoLEfZd5ICLqkTqnyg0Y3hOvozIFIQ2dOciqbXL1MGyiKXCJ7tKuY2e7gUYPDCUZObT6Z+pUX -2nwzV0E8jVHtC7ZcryxjGt9XyD+86V3Em69FmeKjWiS0uqlWPc9vqv9JWL7wqP/0uK3pN/u6uPQL -OvnoQ0IeidiEyxPx2bvhiWC4jChWrBQdnArncevPDt09qZahSL0896+1DSJMwBGB7FY79tOi4lu3 -sgQiUpWAk2nojkxl8ZEDLXB0AuqLZxUpaVICu9ffUGpVRr+goyhhf3DQw6KqLCGqR84onAZFdr+C -GCe01a60y1Dma/RMhnEw6abfFobg2P9A3fvQQoh/ozM6LlweQRGBY84YcWsr7KaKtzFcOmpH4MN5 -WdYgGq/yapiqcrxXStJLnbsQ/LBMQeXtHT1eKJ2czL+zUdqnR+WEUwIDAQABo0IwQDAdBgNVHQ4E -FgQUu69+Aj36pvE8hI6t7jiY7NkyMtQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8w -DQYJKoZIhvcNAQEMBQADggIBAArx1UaEt65Ru2yyTUEUAJNMnMvlwFTPoCWOAvn9sKIN9SCYPBMt -rFaisNZ+EZLpLrqeLppysb0ZRGxhNaKatBYSaVqM4dc+pBroLwP0rmEdEBsqpIt6xf4FpuHA1sj+ -nq6PK7o9mfjYcwlYRm6mnPTXJ9OV2jeDchzTc+CiR5kDOF3VSXkAKRzH7JsgHAckaVd4sjn8OoSg -tZx8jb8uk2IntznaFxiuvTwJaP+EmzzV1gsD41eeFPfR60/IvYcjt7ZJQ3mFXLrrkguhxuhoqEwW -sRqZCuhTLJK7oQkYdQxlqHvLI7cawiiFwxv/0Cti76R7CZGYZ4wUAc1oBmpjIXUDgIiKboHGhfKp -pC3n9KUkEEeDys30jXlYsQab5xoq2Z0B15R97QNKyvDb6KkBPvVWmckejkk9u+UJueBPSZI9FoJA -zMxZxuY67RIuaTxslbH9qh17f4a+Hg4yRvv7E491f0yLS0Zj/gA0QHDBw7mh3aZw4gSzQbzpgJHq -ZJx64SIDqZxubw5lT2yHh17zbqD5daWbQOhTsiedSrnAdyGN/4fy3ryM7xfft0kL0fJuMAsaDk52 -7RH89elWsn2/x20Kk4yl0MC2Hb46TpSi125sC8KKfPog88Tk5c0NqMuRkrF8hey1FGlmDoLnzc7I -LaZRfyHBNVOFBkpdn627G190 ------END CERTIFICATE----- - -USERTrust RSA Certification Authority -===================================== ------BEGIN CERTIFICATE----- -MIIF3jCCA8agAwIBAgIQAf1tMPyjylGoG7xkDjUDLTANBgkqhkiG9w0BAQwFADCBiDELMAkGA1UE -BhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQK -ExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNh -dGlvbiBBdXRob3JpdHkwHhcNMTAwMjAxMDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UE -BhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQK -ExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNh -dGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCAEmUXNg7D2wiz -0KxXDXbtzSfTTK1Qg2HiqiBNCS1kCdzOiZ/MPans9s/B3PHTsdZ7NygRK0faOca8Ohm0X6a9fZ2j -Y0K2dvKpOyuR+OJv0OwWIJAJPuLodMkYtJHUYmTbf6MG8YgYapAiPLz+E/CHFHv25B+O1ORRxhFn -RghRy4YUVD+8M/5+bJz/Fp0YvVGONaanZshyZ9shZrHUm3gDwFA66Mzw3LyeTP6vBZY1H1dat//O -+T23LLb2VN3I5xI6Ta5MirdcmrS3ID3KfyI0rn47aGYBROcBTkZTmzNg95S+UzeQc0PzMsNT79uq -/nROacdrjGCT3sTHDN/hMq7MkztReJVni+49Vv4M0GkPGw/zJSZrM233bkf6c0Plfg6lZrEpfDKE -Y1WJxA3Bk1QwGROs0303p+tdOmw1XNtB1xLaqUkL39iAigmTYo61Zs8liM2EuLE/pDkP2QKe6xJM -lXzzawWpXhaDzLhn4ugTncxbgtNMs+1b/97lc6wjOy0AvzVVdAlJ2ElYGn+SNuZRkg7zJn0cTRe8 -yexDJtC/QV9AqURE9JnnV4eeUB9XVKg+/XRjL7FQZQnmWEIuQxpMtPAlR1n6BB6T1CZGSlCBst6+ -eLf8ZxXhyVeEHg9j1uliutZfVS7qXMYoCAQlObgOK6nyTJccBz8NUvXt7y+CDwIDAQABo0IwQDAd -BgNVHQ4EFgQUU3m/WqorSs9UgOHYm8Cd8rIDZsswDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF -MAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAFzUfA3P9wF9QZllDHPFUp/L+M+ZBn8b2kMVn54CVVeW -FPFSPCeHlCjtHzoBN6J2/FNQwISbxmtOuowhT6KOVWKR82kV2LyI48SqC/3vqOlLVSoGIG1VeCkZ -7l8wXEskEVX/JJpuXior7gtNn3/3ATiUFJVDBwn7YKnuHKsSjKCaXqeYalltiz8I+8jRRa8YFWSQ -Eg9zKC7F4iRO/Fjs8PRF/iKz6y+O0tlFYQXBl2+odnKPi4w2r78NBc5xjeambx9spnFixdjQg3IM -8WcRiQycE0xyNN+81XHfqnHd4blsjDwSXWXavVcStkNr/+XeTWYRUc+ZruwXtuhxkYzeSf7dNXGi -FSeUHM9h4ya7b6NnJSFd5t0dCy5oGzuCr+yDZ4XUmFF0sbmZgIn/f3gZXHlKYC6SQK5MNyosycdi -yA5d9zZbyuAlJQG03RoHnHcAP9Dc1ew91Pq7P8yF1m9/qS3fuQL39ZeatTXaw2ewh0qpKJ4jjv9c -J2vhsE/zB+4ALtRZh8tSQZXq9EfX7mRBVXyNWQKV3WKdwrnuWih0hKWbt5DHDAff9Yk2dDLWKMGw -sAvgnEzDHNb842m1R0aBL6KCq9NjRHDEjf8tM7qtj3u1cIiuPhnPQCjY/MiQu12ZIvVS5ljFH4gx -Q+6IHdfGjjxDah2nGN59PRbxYvnKkKj9 ------END CERTIFICATE----- - -USERTrust ECC Certification Authority -===================================== ------BEGIN CERTIFICATE----- -MIICjzCCAhWgAwIBAgIQXIuZxVqUxdJxVt7NiYDMJjAKBggqhkjOPQQDAzCBiDELMAkGA1UEBhMC -VVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVU -aGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBFQ0MgQ2VydGlmaWNhdGlv -biBBdXRob3JpdHkwHhcNMTAwMjAxMDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMC -VVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVU -aGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBFQ0MgQ2VydGlmaWNhdGlv -biBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQarFRaqfloI+d61SRvU8Za2EurxtW2 -0eZzca7dnNYMYf3boIkDuAUU7FfO7l0/4iGzzvfUinngo4N+LZfQYcTxmdwlkWOrfzCjtHDix6Ez -nPO/LlxTsV+zfTJ/ijTjeXmjQjBAMB0GA1UdDgQWBBQ64QmG1M8ZwpZ2dEl23OA1xmNjmjAOBgNV -HQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjA2Z6EWCNzklwBB -HU6+4WMBzzuqQhFkoJ2UOQIReVx7Hfpkue4WQrO/isIJxOzksU0CMQDpKmFHjFJKS04YcPbWRNZu -9YO6bVi9JNlWSOrvxKJGgYhqOkbRqZtNyWHa0V1Xahg= ------END CERTIFICATE----- - -GlobalSign ECC Root CA - R5 -=========================== ------BEGIN CERTIFICATE----- -MIICHjCCAaSgAwIBAgIRYFlJ4CYuu1X5CneKcflK2GwwCgYIKoZIzj0EAwMwUDEkMCIGA1UECxMb -R2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI1MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQD -EwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoXDTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMb -R2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI1MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQD -EwpHbG9iYWxTaWduMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAER0UOlvt9Xb/pOdEh+J8LttV7HpI6 -SFkc8GIxLcB6KP4ap1yztsyX50XUWPrRd21DosCHZTQKH3rd6zwzocWdTaRvQZU4f8kehOvRnkmS -h5SHDDqFSmafnVmTTZdhBoZKo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAd -BgNVHQ4EFgQUPeYpSJvqB8ohREom3m7e0oPQn1kwCgYIKoZIzj0EAwMDaAAwZQIxAOVpEslu28Yx -uglB4Zf4+/2a4n0Sye18ZNPLBSWLVtmg515dTguDnFt2KaAJJiFqYgIwcdK1j1zqO+F4CYWodZI7 -yFz9SO8NdCKoCOJuxUnOxwy8p2Fp8fc74SrL+SvzZpA3 ------END CERTIFICATE----- - -IdenTrust Commercial Root CA 1 -============================== ------BEGIN CERTIFICATE----- -MIIFYDCCA0igAwIBAgIQCgFCgAAAAUUjyES1AAAAAjANBgkqhkiG9w0BAQsFADBKMQswCQYDVQQG -EwJVUzESMBAGA1UEChMJSWRlblRydXN0MScwJQYDVQQDEx5JZGVuVHJ1c3QgQ29tbWVyY2lhbCBS -b290IENBIDEwHhcNMTQwMTE2MTgxMjIzWhcNMzQwMTE2MTgxMjIzWjBKMQswCQYDVQQGEwJVUzES -MBAGA1UEChMJSWRlblRydXN0MScwJQYDVQQDEx5JZGVuVHJ1c3QgQ29tbWVyY2lhbCBSb290IENB -IDEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCnUBneP5k91DNG8W9RYYKyqU+PZ4ld -hNlT3Qwo2dfw/66VQ3KZ+bVdfIrBQuExUHTRgQ18zZshq0PirK1ehm7zCYofWjK9ouuU+ehcCuz/ -mNKvcbO0U59Oh++SvL3sTzIwiEsXXlfEU8L2ApeN2WIrvyQfYo3fw7gpS0l4PJNgiCL8mdo2yMKi -1CxUAGc1bnO/AljwpN3lsKImesrgNqUZFvX9t++uP0D1bVoE/c40yiTcdCMbXTMTEl3EASX2MN0C -XZ/g1Ue9tOsbobtJSdifWwLziuQkkORiT0/Br4sOdBeo0XKIanoBScy0RnnGF7HamB4HWfp1IYVl -3ZBWzvurpWCdxJ35UrCLvYf5jysjCiN2O/cz4ckA82n5S6LgTrx+kzmEB/dEcH7+B1rlsazRGMzy -NeVJSQjKVsk9+w8YfYs7wRPCTY/JTw436R+hDmrfYi7LNQZReSzIJTj0+kuniVyc0uMNOYZKdHzV -WYfCP04MXFL0PfdSgvHqo6z9STQaKPNBiDoT7uje/5kdX7rL6B7yuVBgwDHTc+XvvqDtMwt0viAg -xGds8AgDelWAf0ZOlqf0Hj7h9tgJ4TNkK2PXMl6f+cB7D3hvl7yTmvmcEpB4eoCHFddydJxVdHix -uuFucAS6T6C6aMN7/zHwcz09lCqxC0EOoP5NiGVreTO01wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMC -AQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU7UQZwNPwBovupHu+QucmVMiONnYwDQYJKoZI -hvcNAQELBQADggIBAA2ukDL2pkt8RHYZYR4nKM1eVO8lvOMIkPkp165oCOGUAFjvLi5+U1KMtlwH -6oi6mYtQlNeCgN9hCQCTrQ0U5s7B8jeUeLBfnLOic7iPBZM4zY0+sLj7wM+x8uwtLRvM7Kqas6pg -ghstO8OEPVeKlh6cdbjTMM1gCIOQ045U8U1mwF10A0Cj7oV+wh93nAbowacYXVKV7cndJZ5t+qnt -ozo00Fl72u1Q8zW/7esUTTHHYPTa8Yec4kjixsU3+wYQ+nVZZjFHKdp2mhzpgq7vmrlR94gjmmmV -YjzlVYA211QC//G5Xc7UI2/YRYRKW2XviQzdFKcgyxilJbQN+QHwotL0AMh0jqEqSI5l2xPE4iUX -feu+h1sXIFRRk0pTAwvsXcoz7WL9RccvW9xYoIA55vrX/hMUpu09lEpCdNTDd1lzzY9GvlU47/ro -kTLql1gEIt44w8y8bckzOmoKaT+gyOpyj4xjhiO9bTyWnpXgSUyqorkqG5w2gXjtw+hG4iZZRHUe -2XWJUc0QhJ1hYMtd+ZciTY6Y5uN/9lu7rs3KSoFrXgvzUeF0K+l+J6fZmUlO+KWA2yUPHGNiiskz -Z2s8EIPGrd6ozRaOjfAHN3Gf8qv8QfXBi+wAN10J5U6A7/qxXDgGpRtK4dw4LTzcqx+QGtVKnO7R -cGzM7vRX+Bi6hG6H ------END CERTIFICATE----- - -IdenTrust Public Sector Root CA 1 -================================= ------BEGIN CERTIFICATE----- -MIIFZjCCA06gAwIBAgIQCgFCgAAAAUUjz0Z8AAAAAjANBgkqhkiG9w0BAQsFADBNMQswCQYDVQQG -EwJVUzESMBAGA1UEChMJSWRlblRydXN0MSowKAYDVQQDEyFJZGVuVHJ1c3QgUHVibGljIFNlY3Rv -ciBSb290IENBIDEwHhcNMTQwMTE2MTc1MzMyWhcNMzQwMTE2MTc1MzMyWjBNMQswCQYDVQQGEwJV -UzESMBAGA1UEChMJSWRlblRydXN0MSowKAYDVQQDEyFJZGVuVHJ1c3QgUHVibGljIFNlY3RvciBS -b290IENBIDEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2IpT8pEiv6EdrCvsnduTy -P4o7ekosMSqMjbCpwzFrqHd2hCa2rIFCDQjrVVi7evi8ZX3yoG2LqEfpYnYeEe4IFNGyRBb06tD6 -Hi9e28tzQa68ALBKK0CyrOE7S8ItneShm+waOh7wCLPQ5CQ1B5+ctMlSbdsHyo+1W/CD80/HLaXI -rcuVIKQxKFdYWuSNG5qrng0M8gozOSI5Cpcu81N3uURF/YTLNiCBWS2ab21ISGHKTN9T0a9SvESf -qy9rg3LvdYDaBjMbXcjaY8ZNzaxmMc3R3j6HEDbhuaR672BQssvKplbgN6+rNBM5Jeg5ZuSYeqoS -mJxZZoY+rfGwyj4GD3vwEUs3oERte8uojHH01bWRNszwFcYr3lEXsZdMUD2xlVl8BX0tIdUAvwFn -ol57plzy9yLxkA2T26pEUWbMfXYD62qoKjgZl3YNa4ph+bz27nb9cCvdKTz4Ch5bQhyLVi9VGxyh -LrXHFub4qjySjmm2AcG1hp2JDws4lFTo6tyePSW8Uybt1as5qsVATFSrsrTZ2fjXctscvG29ZV/v -iDUqZi/u9rNl8DONfJhBaUYPQxxp+pu10GFqzcpL2UyQRqsVWaFHVCkugyhfHMKiq3IXAAaOReyL -4jM9f9oZRORicsPfIsbyVtTdX5Vy7W1f90gDW/3FKqD2cyOEEBsB5wIDAQABo0IwQDAOBgNVHQ8B -Af8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU43HgntinQtnbcZFrlJPrw6PRFKMw -DQYJKoZIhvcNAQELBQADggIBAEf63QqwEZE4rU1d9+UOl1QZgkiHVIyqZJnYWv6IAcVYpZmxI1Qj -t2odIFflAWJBF9MJ23XLblSQdf4an4EKwt3X9wnQW3IV5B4Jaj0z8yGa5hV+rVHVDRDtfULAj+7A -mgjVQdZcDiFpboBhDhXAuM/FSRJSzL46zNQuOAXeNf0fb7iAaJg9TaDKQGXSc3z1i9kKlT/YPyNt -GtEqJBnZhbMX73huqVjRI9PHE+1yJX9dsXNw0H8GlwmEKYBhHfpe/3OsoOOJuBxxFcbeMX8S3OFt -m6/n6J91eEyrRjuazr8FGF1NFTwWmhlQBJqymm9li1JfPFgEKCXAZmExfrngdbkaqIHWchezxQMx -NRF4eKLg6TCMf4DfWN88uieW4oA0beOY02QnrEh+KHdcxiVhJfiFDGX6xDIvpZgF5PgLZxYWxoK4 -Mhn5+bl53B/N66+rDt0b20XkeucC4pVd/GnwU2lhlXV5C15V5jgclKlZM57IcXR5f1GJtshquDDI -ajjDbp7hNxbqBWJMWxJH7ae0s1hWx0nzfxJoCTFx8G34Tkf71oXuxVhAGaQdp/lLQzfcaFpPz+vC -ZHTetBXZ9FRUGi8c15dxVJCO2SCdUyt/q4/i6jC8UDfv8Ue1fXwsBOxonbRJRBD0ckscZOf85muQ -3Wl9af0AVqW3rLatt8o+Ae+c ------END CERTIFICATE----- - -Entrust Root Certification Authority - G2 -========================================= ------BEGIN CERTIFICATE----- -MIIEPjCCAyagAwIBAgIESlOMKDANBgkqhkiG9w0BAQsFADCBvjELMAkGA1UEBhMCVVMxFjAUBgNV -BAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwtdGVy -bXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ug -b25seTEyMDAGA1UEAxMpRW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzIw -HhcNMDkwNzA3MTcyNTU0WhcNMzAxMjA3MTc1NTU0WjCBvjELMAkGA1UEBhMCVVMxFjAUBgNVBAoT -DUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwtdGVybXMx -OTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25s -eTEyMDAGA1UEAxMpRW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzIwggEi -MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6hLZy254Ma+KZ6TABp3bqMriVQRrJ2mFOWHLP -/vaCeb9zYQYKpSfYs1/TRU4cctZOMvJyig/3gxnQaoCAAEUesMfnmr8SVycco2gvCoe9amsOXmXz -HHfV1IWNcCG0szLni6LVhjkCsbjSR87kyUnEO6fe+1R9V77w6G7CebI6C1XiUJgWMhNcL3hWwcKU -s/Ja5CeanyTXxuzQmyWC48zCxEXFjJd6BmsqEZ+pCm5IO2/b1BEZQvePB7/1U1+cPvQXLOZprE4y -TGJ36rfo5bs0vBmLrpxR57d+tVOxMyLlbc9wPBr64ptntoP0jaWvYkxN4FisZDQSA/i2jZRjJKRx -AgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqciZ6 -0B7vfec7aVHUbI2fkBJmqzANBgkqhkiG9w0BAQsFAAOCAQEAeZ8dlsa2eT8ijYfThwMEYGprmi5Z -iXMRrEPR9RP/jTkrwPK9T3CMqS/qF8QLVJ7UG5aYMzyorWKiAHarWWluBh1+xLlEjZivEtRh2woZ -Rkfz6/djwUAFQKXSt/S1mja/qYh2iARVBCuch38aNzx+LaUa2NSJXsq9rD1s2G2v1fN2D807iDgi -nWyTmsQ9v4IbZT+mD12q/OWyFcq1rca8PdCE6OoGcrBNOTJ4vz4RnAuknZoh8/CbCzB428Hch0P+ -vGOaysXCHMnHjf87ElgI5rY97HosTvuDls4MPGmHVHOkc8KT/1EQrBVUAdj8BbGJoX90g5pJ19xO -e4pIb4tF9g== ------END CERTIFICATE----- - -Entrust Root Certification Authority - EC1 -========================================== ------BEGIN CERTIFICATE----- -MIIC+TCCAoCgAwIBAgINAKaLeSkAAAAAUNCR+TAKBggqhkjOPQQDAzCBvzELMAkGA1UEBhMCVVMx -FjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVn -YWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDEyIEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXpl -ZCB1c2Ugb25seTEzMDEGA1UEAxMqRW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5 -IC0gRUMxMB4XDTEyMTIxODE1MjUzNloXDTM3MTIxODE1NTUzNlowgb8xCzAJBgNVBAYTAlVTMRYw -FAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1c3QubmV0L2xlZ2Fs -LXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxMiBFbnRydXN0LCBJbmMuIC0gZm9yIGF1dGhvcml6ZWQg -dXNlIG9ubHkxMzAxBgNVBAMTKkVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAt -IEVDMTB2MBAGByqGSM49AgEGBSuBBAAiA2IABIQTydC6bUF74mzQ61VfZgIaJPRbiWlH47jCffHy -AsWfoPZb1YsGGYZPUxBtByQnoaD41UcZYUx9ypMn6nQM72+WCf5j7HBdNq1nd67JnXxVRDqiY1Ef -9eNi1KlHBz7MIKNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYE -FLdj5xrdjekIplWDpOBqUEFlEUJJMAoGCCqGSM49BAMDA2cAMGQCMGF52OVCR98crlOZF7ZvHH3h -vxGU0QOIdeSNiaSKd0bebWHvAvX7td/M/k7//qnmpwIwW5nXhTcGtXsI/esni0qU+eH6p44mCOh8 -kmhtc9hvJqwhAriZtyZBWyVgrtBIGu4G ------END CERTIFICATE----- - -CFCA EV ROOT -============ ------BEGIN CERTIFICATE----- -MIIFjTCCA3WgAwIBAgIEGErM1jANBgkqhkiG9w0BAQsFADBWMQswCQYDVQQGEwJDTjEwMC4GA1UE -CgwnQ2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRUwEwYDVQQDDAxDRkNB -IEVWIFJPT1QwHhcNMTIwODA4MDMwNzAxWhcNMjkxMjMxMDMwNzAxWjBWMQswCQYDVQQGEwJDTjEw -MC4GA1UECgwnQ2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRUwEwYDVQQD -DAxDRkNBIEVWIFJPT1QwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDXXWvNED8fBVnV -BU03sQ7smCuOFR36k0sXgiFxEFLXUWRwFsJVaU2OFW2fvwwbwuCjZ9YMrM8irq93VCpLTIpTUnrD -7i7es3ElweldPe6hL6P3KjzJIx1qqx2hp/Hz7KDVRM8Vz3IvHWOX6Jn5/ZOkVIBMUtRSqy5J35DN -uF++P96hyk0g1CXohClTt7GIH//62pCfCqktQT+x8Rgp7hZZLDRJGqgG16iI0gNyejLi6mhNbiyW -ZXvKWfry4t3uMCz7zEasxGPrb382KzRzEpR/38wmnvFyXVBlWY9ps4deMm/DGIq1lY+wejfeWkU7 -xzbh72fROdOXW3NiGUgthxwG+3SYIElz8AXSG7Ggo7cbcNOIabla1jj0Ytwli3i/+Oh+uFzJlU9f -py25IGvPa931DfSCt/SyZi4QKPaXWnuWFo8BGS1sbn85WAZkgwGDg8NNkt0yxoekN+kWzqotaK8K -gWU6cMGbrU1tVMoqLUuFG7OA5nBFDWteNfB/O7ic5ARwiRIlk9oKmSJgamNgTnYGmE69g60dWIol -hdLHZR4tjsbftsbhf4oEIRUpdPA+nJCdDC7xij5aqgwJHsfVPKPtl8MeNPo4+QgO48BdK4PRVmrJ -tqhUUy54Mmc9gn900PvhtgVguXDbjgv5E1hvcWAQUhC5wUEJ73IfZzF4/5YFjQIDAQABo2MwYTAf -BgNVHSMEGDAWgBTj/i39KNALtbq2osS/BqoFjJP7LzAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB -/wQEAwIBBjAdBgNVHQ4EFgQU4/4t/SjQC7W6tqLEvwaqBYyT+y8wDQYJKoZIhvcNAQELBQADggIB -ACXGumvrh8vegjmWPfBEp2uEcwPenStPuiB/vHiyz5ewG5zz13ku9Ui20vsXiObTej/tUxPQ4i9q -ecsAIyjmHjdXNYmEwnZPNDatZ8POQQaIxffu2Bq41gt/UP+TqhdLjOztUmCypAbqTuv0axn96/Ua -4CUqmtzHQTb3yHQFhDmVOdYLO6Qn+gjYXB74BGBSESgoA//vU2YApUo0FmZ8/Qmkrp5nGm9BC2sG -E5uPhnEFtC+NiWYzKXZUmhH4J/qyP5Hgzg0b8zAarb8iXRvTvyUFTeGSGn+ZnzxEk8rUQElsgIfX -BDrDMlI1Dlb4pd19xIsNER9Tyx6yF7Zod1rg1MvIB671Oi6ON7fQAUtDKXeMOZePglr4UeWJoBjn -aH9dCi77o0cOPaYjesYBx4/IXr9tgFa+iiS6M+qf4TIRnvHST4D2G0CvOJ4RUHlzEhLN5mydLIhy -PDCBBpEi6lmt2hkuIsKNuYyH4Ga8cyNfIWRjgEj1oDwYPZTISEEdQLpe/v5WOaHIz16eGWRGENoX -kbcFgKyLmZJ956LYBws2J+dIeWCKw9cTXPhyQN9Ky8+ZAAoACxGV2lZFA4gKn2fQ1XmxqI1AbQ3C -ekD6819kR5LLU7m7Wc5P/dAVUwHY3+vZ5nbv0CO7O6l5s9UCKc2Jo5YPSjXnTkLAdc0Hz+Ys63su ------END CERTIFICATE----- - -OISTE WISeKey Global Root GB CA -=============================== ------BEGIN CERTIFICATE----- -MIIDtTCCAp2gAwIBAgIQdrEgUnTwhYdGs/gjGvbCwDANBgkqhkiG9w0BAQsFADBtMQswCQYDVQQG -EwJDSDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUgRm91bmRhdGlvbiBFbmRvcnNl -ZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9iYWwgUm9vdCBHQiBDQTAeFw0xNDEyMDExNTAw -MzJaFw0zOTEyMDExNTEwMzFaMG0xCzAJBgNVBAYTAkNIMRAwDgYDVQQKEwdXSVNlS2V5MSIwIAYD -VQQLExlPSVNURSBGb3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5IEds -b2JhbCBSb290IEdCIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2Be3HEokKtaX -scriHvt9OO+Y9bI5mE4nuBFde9IllIiCFSZqGzG7qFshISvYD06fWvGxWuR51jIjK+FTzJlFXHtP -rby/h0oLS5daqPZI7H17Dc0hBt+eFf1Biki3IPShehtX1F1Q/7pn2COZH8g/497/b1t3sWtuuMlk -9+HKQUYOKXHQuSP8yYFfTvdv37+ErXNku7dCjmn21HYdfp2nuFeKUWdy19SouJVUQHMD9ur06/4o -Qnc/nSMbsrY9gBQHTC5P99UKFg29ZkM3fiNDecNAhvVMKdqOmq0NpQSHiB6F4+lT1ZvIiwNjeOvg -GUpuuy9rM2RYk61pv48b74JIxwIDAQABo1EwTzALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB -/zAdBgNVHQ4EFgQUNQ/INmNe4qPs+TtmFc5RUuORmj0wEAYJKwYBBAGCNxUBBAMCAQAwDQYJKoZI -hvcNAQELBQADggEBAEBM+4eymYGQfp3FsLAmzYh7KzKNbrghcViXfa43FK8+5/ea4n32cZiZBKpD -dHij40lhPnOMTZTg+XHEthYOU3gf1qKHLwI5gSk8rxWYITD+KJAAjNHhy/peyP34EEY7onhCkRd0 -VQreUGdNZtGn//3ZwLWoo4rOZvUPQ82nK1d7Y0Zqqi5S2PTt4W2tKZB4SLrhI6qjiey1q5bAtEui -HZeeevJuQHHfaPFlTc58Bd9TZaml8LGXBHAVRgOY1NK/VLSgWH1Sb9pWJmLU2NuJMW8c8CLC02Ic -Nc1MaRVUGpCY3useX8p3x8uOPUNpnJpY0CQ73xtAln41rYHHTnG6iBM= ------END CERTIFICATE----- - -SZAFIR ROOT CA2 -=============== ------BEGIN CERTIFICATE----- -MIIDcjCCAlqgAwIBAgIUPopdB+xV0jLVt+O2XwHrLdzk1uQwDQYJKoZIhvcNAQELBQAwUTELMAkG -A1UEBhMCUEwxKDAmBgNVBAoMH0tyYWpvd2EgSXpiYSBSb3psaWN6ZW5pb3dhIFMuQS4xGDAWBgNV -BAMMD1NaQUZJUiBST09UIENBMjAeFw0xNTEwMTkwNzQzMzBaFw0zNTEwMTkwNzQzMzBaMFExCzAJ -BgNVBAYTAlBMMSgwJgYDVQQKDB9LcmFqb3dhIEl6YmEgUm96bGljemVuaW93YSBTLkEuMRgwFgYD -VQQDDA9TWkFGSVIgUk9PVCBDQTIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC3vD5Q -qEvNQLXOYeeWyrSh2gwisPq1e3YAd4wLz32ohswmUeQgPYUM1ljj5/QqGJ3a0a4m7utT3PSQ1hNK -DJA8w/Ta0o4NkjrcsbH/ON7Dui1fgLkCvUqdGw+0w8LBZwPd3BucPbOw3gAeqDRHu5rr/gsUvTaE -2g0gv/pby6kWIK05YO4vdbbnl5z5Pv1+TW9NL++IDWr63fE9biCloBK0TXC5ztdyO4mTp4CEHCdJ -ckm1/zuVnsHMyAHs6A6KCpbns6aH5db5BSsNl0BwPLqsdVqc1U2dAgrSS5tmS0YHF2Wtn2yIANwi -ieDhZNRnvDF5YTy7ykHNXGoAyDw4jlivAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0P -AQH/BAQDAgEGMB0GA1UdDgQWBBQuFqlKGLXLzPVvUPMjX/hd56zwyDANBgkqhkiG9w0BAQsFAAOC -AQEAtXP4A9xZWx126aMqe5Aosk3AM0+qmrHUuOQn/6mWmc5G4G18TKI4pAZw8PRBEew/R40/cof5 -O/2kbytTAOD/OblqBw7rHRz2onKQy4I9EYKL0rufKq8h5mOGnXkZ7/e7DDWQw4rtTw/1zBLZpD67 -oPwglV9PJi8RI4NOdQcPv5vRtB3pEAT+ymCPoky4rc/hkA/NrgrHXXu3UNLUYfrVFdvXn4dRVOul -4+vJhaAlIDf7js4MNIThPIGyd05DpYhfhmehPea0XGG2Ptv+tyjFogeutcrKjSoS75ftwjCkySp6 -+/NNIxuZMzSgLvWpCz/UXeHPhJ/iGcJfitYgHuNztw== ------END CERTIFICATE----- - -Certum Trusted Network CA 2 -=========================== ------BEGIN CERTIFICATE----- -MIIF0jCCA7qgAwIBAgIQIdbQSk8lD8kyN/yqXhKN6TANBgkqhkiG9w0BAQ0FADCBgDELMAkGA1UE -BhMCUEwxIjAgBgNVBAoTGVVuaXpldG8gVGVjaG5vbG9naWVzIFMuQS4xJzAlBgNVBAsTHkNlcnR1 -bSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEkMCIGA1UEAxMbQ2VydHVtIFRydXN0ZWQgTmV0d29y -ayBDQSAyMCIYDzIwMTExMDA2MDgzOTU2WhgPMjA0NjEwMDYwODM5NTZaMIGAMQswCQYDVQQGEwJQ -TDEiMCAGA1UEChMZVW5pemV0byBUZWNobm9sb2dpZXMgUy5BLjEnMCUGA1UECxMeQ2VydHVtIENl -cnRpZmljYXRpb24gQXV0aG9yaXR5MSQwIgYDVQQDExtDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENB -IDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC9+Xj45tWADGSdhhuWZGc/IjoedQF9 -7/tcZ4zJzFxrqZHmuULlIEub2pt7uZld2ZuAS9eEQCsn0+i6MLs+CRqnSZXvK0AkwpfHp+6bJe+o -CgCXhVqqndwpyeI1B+twTUrWwbNWuKFBOJvR+zF/j+Bf4bE/D44WSWDXBo0Y+aomEKsq09DRZ40b -Rr5HMNUuctHFY9rnY3lEfktjJImGLjQ/KUxSiyqnwOKRKIm5wFv5HdnnJ63/mgKXwcZQkpsCLL2p -uTRZCr+ESv/f/rOf69me4Jgj7KZrdxYq28ytOxykh9xGc14ZYmhFV+SQgkK7QtbwYeDBoz1mo130 -GO6IyY0XRSmZMnUCMe4pJshrAua1YkV/NxVaI2iJ1D7eTiew8EAMvE0Xy02isx7QBlrd9pPPV3WZ -9fqGGmd4s7+W/jTcvedSVuWz5XV710GRBdxdaeOVDUO5/IOWOZV7bIBaTxNyxtd9KXpEulKkKtVB -Rgkg/iKgtlswjbyJDNXXcPiHUv3a76xRLgezTv7QCdpw75j6VuZt27VXS9zlLCUVyJ4ueE742pye -hizKV/Ma5ciSixqClnrDvFASadgOWkaLOusm+iPJtrCBvkIApPjW/jAux9JG9uWOdf3yzLnQh1vM -BhBgu4M1t15n3kfsmUjxpKEV/q2MYo45VU85FrmxY53/twIDAQABo0IwQDAPBgNVHRMBAf8EBTAD -AQH/MB0GA1UdDgQWBBS2oVQ5AsOgP46KvPrU+Bym0ToO/TAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZI -hvcNAQENBQADggIBAHGlDs7k6b8/ONWJWsQCYftMxRQXLYtPU2sQF/xlhMcQSZDe28cmk4gmb3DW -Al45oPePq5a1pRNcgRRtDoGCERuKTsZPpd1iHkTfCVn0W3cLN+mLIMb4Ck4uWBzrM9DPhmDJ2vuA -L55MYIR4PSFk1vtBHxgP58l1cb29XN40hz5BsA72udY/CROWFC/emh1auVbONTqwX3BNXuMp8SMo -clm2q8KMZiYcdywmdjWLKKdpoPk79SPdhRB0yZADVpHnr7pH1BKXESLjokmUbOe3lEu6LaTaM4tM -pkT/WjzGHWTYtTHkpjx6qFcL2+1hGsvxznN3Y6SHb0xRONbkX8eftoEq5IVIeVheO/jbAoJnwTnb -w3RLPTYe+SmTiGhbqEQZIfCn6IENLOiTNrQ3ssqwGyZ6miUfmpqAnksqP/ujmv5zMnHCnsZy4Ypo -J/HkD7TETKVhk/iXEAcqMCWpuchxuO9ozC1+9eB+D4Kob7a6bINDd82Kkhehnlt4Fj1F4jNy3eFm -ypnTycUm/Q1oBEauttmbjL4ZvrHG8hnjXALKLNhvSgfZyTXaQHXyxKcZb55CEJh15pWLYLztxRLX -is7VmFxWlgPF7ncGNf/P5O4/E2Hu29othfDNrp2yGAlFw5Khchf8R7agCyzxxN5DaAhqXzvwdmP7 -zAYspsbiDrW5viSP ------END CERTIFICATE----- - -Hellenic Academic and Research Institutions RootCA 2015 -======================================================= ------BEGIN CERTIFICATE----- -MIIGCzCCA/OgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBpjELMAkGA1UEBhMCR1IxDzANBgNVBAcT -BkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0 -aW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNVBAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNl -YXJjaCBJbnN0aXR1dGlvbnMgUm9vdENBIDIwMTUwHhcNMTUwNzA3MTAxMTIxWhcNNDAwNjMwMTAx -MTIxWjCBpjELMAkGA1UEBhMCR1IxDzANBgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMg -QWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNV -BAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgUm9vdENBIDIw -MTUwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDC+Kk/G4n8PDwEXT2QNrCROnk8Zlrv -bTkBSRq0t89/TSNTt5AA4xMqKKYx8ZEA4yjsriFBzh/a/X0SWwGDD7mwX5nh8hKDgE0GPt+sr+eh -iGsxr/CL0BgzuNtFajT0AoAkKAoCFZVedioNmToUW/bLy1O8E00BiDeUJRtCvCLYjqOWXjrZMts+ -6PAQZe104S+nfK8nNLspfZu2zwnI5dMK/IhlZXQK3HMcXM1AsRzUtoSMTFDPaI6oWa7CJ06CojXd -FPQf/7J31Ycvqm59JCfnxssm5uX+Zwdj2EUN3TpZZTlYepKZcj2chF6IIbjV9Cz82XBST3i4vTwr -i5WY9bPRaM8gFH5MXF/ni+X1NYEZN9cRCLdmvtNKzoNXADrDgfgXy5I2XdGj2HUb4Ysn6npIQf1F -GQatJ5lOwXBH3bWfgVMS5bGMSF0xQxfjjMZ6Y5ZLKTBOhE5iGV48zpeQpX8B653g+IuJ3SWYPZK2 -fu/Z8VFRfS0myGlZYeCsargqNhEEelC9MoS+L9xy1dcdFkfkR2YgP/SWxa+OAXqlD3pk9Q0Yh9mu -iNX6hME6wGkoLfINaFGq46V3xqSQDqE3izEjR8EJCOtu93ib14L8hCCZSRm2Ekax+0VVFqmjZayc -Bw/qa9wfLgZy7IaIEuQt218FL+TwA9MmM+eAws1CoRc0CwIDAQABo0IwQDAPBgNVHRMBAf8EBTAD -AQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUcRVnyMjJvXVdctA4GGqd83EkVAswDQYJKoZI -hvcNAQELBQADggIBAHW7bVRLqhBYRjTyYtcWNl0IXtVsyIe9tC5G8jH4fOpCtZMWVdyhDBKg2mF+ -D1hYc2Ryx+hFjtyp8iY/xnmMsVMIM4GwVhO+5lFc2JsKT0ucVlMC6U/2DWDqTUJV6HwbISHTGzrM -d/K4kPFox/la/vot9L/J9UUbzjgQKjeKeaO04wlshYaT/4mWJ3iBj2fjRnRUjtkNaeJK9E10A/+y -d+2VZ5fkscWrv2oj6NSU4kQoYsRL4vDY4ilrGnB+JGGTe08DMiUNRSQrlrRGar9KC/eaj8GsGsVn -82800vpzY4zvFrCopEYq+OsS7HK07/grfoxSwIuEVPkvPuNVqNxmsdnhX9izjFk0WaSrT2y7Hxjb -davYy5LNlDhhDgcGH0tGEPEVvo2FXDtKK4F5D7Rpn0lQl033DlZdwJVqwjbDG2jJ9SrcR5q+ss7F -Jej6A7na+RZukYT1HCjI/CbM1xyQVqdfbzoEvM14iQuODy+jqk+iGxI9FghAD/FGTNeqewjBCvVt -J94Cj8rDtSvK6evIIVM4pcw72Hc3MKJP2W/R8kCtQXoXxdZKNYm3QdV8hn9VTYNKpXMgwDqvkPGa -JI7ZjnHKe7iG2rKPmT4dEw0SEe7Uq/DpFXYC5ODfqiAeW2GFZECpkJcNrVPSWh2HagCXZWK0vm9q -p/UsQu0yrbYhnr68 ------END CERTIFICATE----- - -Hellenic Academic and Research Institutions ECC RootCA 2015 -=========================================================== ------BEGIN CERTIFICATE----- -MIICwzCCAkqgAwIBAgIBADAKBggqhkjOPQQDAjCBqjELMAkGA1UEBhMCR1IxDzANBgNVBAcTBkF0 -aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9u -cyBDZXJ0LiBBdXRob3JpdHkxRDBCBgNVBAMTO0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJj -aCBJbnN0aXR1dGlvbnMgRUNDIFJvb3RDQSAyMDE1MB4XDTE1MDcwNzEwMzcxMloXDTQwMDYzMDEw -MzcxMlowgaoxCzAJBgNVBAYTAkdSMQ8wDQYDVQQHEwZBdGhlbnMxRDBCBgNVBAoTO0hlbGxlbmlj -IEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgQ2VydC4gQXV0aG9yaXR5MUQwQgYD -VQQDEztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25zIEVDQyBSb290 -Q0EgMjAxNTB2MBAGByqGSM49AgEGBSuBBAAiA2IABJKgQehLgoRc4vgxEZmGZE4JJS+dQS8KrjVP -dJWyUWRrjWvmP3CV8AVER6ZyOFB2lQJajq4onvktTpnvLEhvTCUp6NFxW98dwXU3tNf6e3pCnGoK -Vlp8aQuqgAkkbH7BRqNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0O -BBYEFLQiC4KZJAEOnLvkDv2/+5cgk5kqMAoGCCqGSM49BAMCA2cAMGQCMGfOFmI4oqxiRaeplSTA -GiecMjvAwNW6qef4BENThe5SId6d9SWDPp5YSy/XZxMOIQIwBeF1Ad5o7SofTUwJCA3sS61kFyjn -dc5FZXIhF8siQQ6ME5g4mlRtm8rifOoCWCKR ------END CERTIFICATE----- - -ISRG Root X1 -============ ------BEGIN CERTIFICATE----- -MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAwTzELMAkGA1UE -BhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2VhcmNoIEdyb3VwMRUwEwYDVQQD -EwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQG -EwJVUzEpMCcGA1UEChMgSW50ZXJuZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMT -DElTUkcgUm9vdCBYMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54r -Vygch77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+0TM8ukj1 -3Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6UA5/TR5d8mUgjU+g4rk8K -b4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sWT8KOEUt+zwvo/7V3LvSye0rgTBIlDHCN -Aymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyHB5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ -4Q7e2RCOFvu396j3x+UCB5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf -1b0SHzUvKBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWnOlFu -hjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTnjh8BCNAw1FtxNrQH -usEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbwqHyGO0aoSCqI3Haadr8faqU9GY/r -OPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CIrU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4G -A1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY -9umbbjANBgkqhkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL -ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ3BebYhtF8GaV -0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KKNFtY2PwByVS5uCbMiogziUwt -hDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJw -TdwJx4nLCgdNbOhdjsnvzqvHu7UrTkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nx -e5AW0wdeRlN8NwdCjNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZA -JzVcoyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq4RgqsahD -YVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPAmRGunUHBcnWEvgJBQl9n -JEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57demyPxgcYxn/eR44/KJ4EBs+lVDR3veyJ -m+kXQ99b21/+jh5Xos1AnX5iItreGCc= ------END CERTIFICATE----- - -AC RAIZ FNMT-RCM -================ ------BEGIN CERTIFICATE----- -MIIFgzCCA2ugAwIBAgIPXZONMGc2yAYdGsdUhGkHMA0GCSqGSIb3DQEBCwUAMDsxCzAJBgNVBAYT -AkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJWiBGTk1ULVJDTTAeFw0wODEw -MjkxNTU5NTZaFw0zMDAxMDEwMDAwMDBaMDsxCzAJBgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJD -TTEZMBcGA1UECwwQQUMgUkFJWiBGTk1ULVJDTTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC -ggIBALpxgHpMhm5/yBNtwMZ9HACXjywMI7sQmkCpGreHiPibVmr75nuOi5KOpyVdWRHbNi63URcf -qQgfBBckWKo3Shjf5TnUV/3XwSyRAZHiItQDwFj8d0fsjz50Q7qsNI1NOHZnjrDIbzAzWHFctPVr -btQBULgTfmxKo0nRIBnuvMApGGWn3v7v3QqQIecaZ5JCEJhfTzC8PhxFtBDXaEAUwED653cXeuYL -j2VbPNmaUtu1vZ5Gzz3rkQUCwJaydkxNEJY7kvqcfw+Z374jNUUeAlz+taibmSXaXvMiwzn15Cou -08YfxGyqxRxqAQVKL9LFwag0Jl1mpdICIfkYtwb1TplvqKtMUejPUBjFd8g5CSxJkjKZqLsXF3mw -WsXmo8RZZUc1g16p6DULmbvkzSDGm0oGObVo/CK67lWMK07q87Hj/LaZmtVC+nFNCM+HHmpxffnT -tOmlcYF7wk5HlqX2doWjKI/pgG6BU6VtX7hI+cL5NqYuSf+4lsKMB7ObiFj86xsc3i1w4peSMKGJ -47xVqCfWS+2QrYv6YyVZLag13cqXM7zlzced0ezvXg5KkAYmY6252TUtB7p2ZSysV4999AeU14EC -ll2jB0nVetBX+RvnU0Z1qrB5QstocQjpYL05ac70r8NWQMetUqIJ5G+GR4of6ygnXYMgrwTJbFaa -i0b1AgMBAAGjgYMwgYAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE -FPd9xf3E6Jobd2Sn9R2gzL+HYJptMD4GA1UdIAQ3MDUwMwYEVR0gADArMCkGCCsGAQUFBwIBFh1o -dHRwOi8vd3d3LmNlcnQuZm5tdC5lcy9kcGNzLzANBgkqhkiG9w0BAQsFAAOCAgEAB5BK3/MjTvDD -nFFlm5wioooMhfNzKWtN/gHiqQxjAb8EZ6WdmF/9ARP67Jpi6Yb+tmLSbkyU+8B1RXxlDPiyN8+s -D8+Nb/kZ94/sHvJwnvDKuO+3/3Y3dlv2bojzr2IyIpMNOmqOFGYMLVN0V2Ue1bLdI4E7pWYjJ2cJ -j+F3qkPNZVEI7VFY/uY5+ctHhKQV8Xa7pO6kO8Rf77IzlhEYt8llvhjho6Tc+hj507wTmzl6NLrT -Qfv6MooqtyuGC2mDOL7Nii4LcK2NJpLuHvUBKwrZ1pebbuCoGRw6IYsMHkCtA+fdZn71uSANA+iW -+YJF1DngoABd15jmfZ5nc8OaKveri6E6FO80vFIOiZiaBECEHX5FaZNXzuvO+FB8TxxuBEOb+dY7 -Ixjp6o7RTUaN8Tvkasq6+yO3m/qZASlaWFot4/nUbQ4mrcFuNLwy+AwF+mWj2zs3gyLp1txyM/1d -8iC9djwj2ij3+RvrWWTV3F9yfiD8zYm1kGdNYno/Tq0dwzn+evQoFt9B9kiABdcPUXmsEKvU7ANm -5mqwujGSQkBqvjrTcuFqN1W8rB2Vt2lh8kORdOag0wokRqEIr9baRRmW1FMdW4R58MD3R++Lj8UG -rp1MYp3/RgT408m2ECVAdf4WqslKYIYvuu8wd+RU4riEmViAqhOLUTpPSPaLtrM= ------END CERTIFICATE----- - -Amazon Root CA 1 -================ ------BEGIN CERTIFICATE----- -MIIDQTCCAimgAwIBAgITBmyfz5m/jAo54vB4ikPmljZbyjANBgkqhkiG9w0BAQsFADA5MQswCQYD -VQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24gUm9vdCBDQSAxMB4XDTE1 -MDUyNjAwMDAwMFoXDTM4MDExNzAwMDAwMFowOTELMAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpv -bjEZMBcGA1UEAxMQQW1hem9uIFJvb3QgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC -ggEBALJ4gHHKeNXjca9HgFB0fW7Y14h29Jlo91ghYPl0hAEvrAIthtOgQ3pOsqTQNroBvo3bSMgH -FzZM9O6II8c+6zf1tRn4SWiw3te5djgdYZ6k/oI2peVKVuRF4fn9tBb6dNqcmzU5L/qwIFAGbHrQ -gLKm+a/sRxmPUDgH3KKHOVj4utWp+UhnMJbulHheb4mjUcAwhmahRWa6VOujw5H5SNz/0egwLX0t -dHA114gk957EWW67c4cX8jJGKLhD+rcdqsq08p8kDi1L93FcXmn/6pUCyziKrlA4b9v7LWIbxcce -VOF34GfID5yHI9Y/QCB/IIDEgEw+OyQmjgSubJrIqg0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB -/zAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0OBBYEFIQYzIU07LwMlJQuCFmcx7IQTgoIMA0GCSqGSIb3 -DQEBCwUAA4IBAQCY8jdaQZChGsV2USggNiMOruYou6r4lK5IpDB/G/wkjUu0yKGX9rbxenDIU5PM -CCjjmCXPI6T53iHTfIUJrU6adTrCC2qJeHZERxhlbI1Bjjt/msv0tadQ1wUsN+gDS63pYaACbvXy -8MWy7Vu33PqUXHeeE6V/Uq2V8viTO96LXFvKWlJbYK8U90vvo/ufQJVtMVT8QtPHRh8jrdkPSHCa -2XV4cdFyQzR1bldZwgJcJmApzyMZFo6IQ6XU5MsI+yMRQ+hDKXJioaldXgjUkK642M4UwtBV8ob2 -xJNDd2ZhwLnoQdeXeGADbkpyrqXRfboQnoZsG4q5WTP468SQvvG5 ------END CERTIFICATE----- - -Amazon Root CA 2 -================ ------BEGIN CERTIFICATE----- -MIIFQTCCAymgAwIBAgITBmyf0pY1hp8KD+WGePhbJruKNzANBgkqhkiG9w0BAQwFADA5MQswCQYD -VQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24gUm9vdCBDQSAyMB4XDTE1 -MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpv -bjEZMBcGA1UEAxMQQW1hem9uIFJvb3QgQ0EgMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC -ggIBAK2Wny2cSkxKgXlRmeyKy2tgURO8TW0G/LAIjd0ZEGrHJgw12MBvIITplLGbhQPDW9tK6Mj4 -kHbZW0/jTOgGNk3Mmqw9DJArktQGGWCsN0R5hYGCrVo34A3MnaZMUnbqQ523BNFQ9lXg1dKmSYXp -N+nKfq5clU1Imj+uIFptiJXZNLhSGkOQsL9sBbm2eLfq0OQ6PBJTYv9K8nu+NQWpEjTj82R0Yiw9 -AElaKP4yRLuH3WUnAnE72kr3H9rN9yFVkE8P7K6C4Z9r2UXTu/Bfh+08LDmG2j/e7HJV63mjrdvd -fLC6HM783k81ds8P+HgfajZRRidhW+mez/CiVX18JYpvL7TFz4QuK/0NURBs+18bvBt+xa47mAEx -kv8LV/SasrlX6avvDXbR8O70zoan4G7ptGmh32n2M8ZpLpcTnqWHsFcQgTfJU7O7f/aS0ZzQGPSS -btqDT6ZjmUyl+17vIWR6IF9sZIUVyzfpYgwLKhbcAS4y2j5L9Z469hdAlO+ekQiG+r5jqFoz7Mt0 -Q5X5bGlSNscpb/xVA1wf+5+9R+vnSUeVC06JIglJ4PVhHvG/LopyboBZ/1c6+XUyo05f7O0oYtlN -c/LMgRdg7c3r3NunysV+Ar3yVAhU/bQtCSwXVEqY0VThUWcI0u1ufm8/0i2BWSlmy5A5lREedCf+ -3euvAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSw -DPBMMPQFWAJI/TPlUq9LhONmUjANBgkqhkiG9w0BAQwFAAOCAgEAqqiAjw54o+Ci1M3m9Zh6O+oA -A7CXDpO8Wqj2LIxyh6mx/H9z/WNxeKWHWc8w4Q0QshNabYL1auaAn6AFC2jkR2vHat+2/XcycuUY -+gn0oJMsXdKMdYV2ZZAMA3m3MSNjrXiDCYZohMr/+c8mmpJ5581LxedhpxfL86kSk5Nrp+gvU5LE -YFiwzAJRGFuFjWJZY7attN6a+yb3ACfAXVU3dJnJUH/jWS5E4ywl7uxMMne0nxrpS10gxdr9HIcW -xkPo1LsmmkVwXqkLN1PiRnsn/eBG8om3zEK2yygmbtmlyTrIQRNg91CMFa6ybRoVGld45pIq2WWQ -gj9sAq+uEjonljYE1x2igGOpm/HlurR8FLBOybEfdF849lHqm/osohHUqS0nGkWxr7JOcQ3AWEbW -aQbLU8uz/mtBzUF+fUwPfHJ5elnNXkoOrJupmHN5fLT0zLm4BwyydFy4x2+IoZCn9Kr5v2c69BoV -Yh63n749sSmvZ6ES8lgQGVMDMBu4Gon2nL2XA46jCfMdiyHxtN/kHNGfZQIG6lzWE7OE76KlXIx3 -KadowGuuQNKotOrN8I1LOJwZmhsoVLiJkO/KdYE+HvJkJMcYr07/R54H9jVlpNMKVv/1F2Rs76gi -JUmTtt8AF9pYfl3uxRuw0dFfIRDH+fO6AgonB8Xx1sfT4PsJYGw= ------END CERTIFICATE----- - -Amazon Root CA 3 -================ ------BEGIN CERTIFICATE----- -MIIBtjCCAVugAwIBAgITBmyf1XSXNmY/Owua2eiedgPySjAKBggqhkjOPQQDAjA5MQswCQYDVQQG -EwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24gUm9vdCBDQSAzMB4XDTE1MDUy -NjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZ -MBcGA1UEAxMQQW1hem9uIFJvb3QgQ0EgMzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABCmXp8ZB -f8ANm+gBG1bG8lKlui2yEujSLtf6ycXYqm0fc4E7O5hrOXwzpcVOho6AF2hiRVd9RFgdszflZwjr -Zt6jQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSrttvXBp43 -rDCGB5Fwx5zEGbF4wDAKBggqhkjOPQQDAgNJADBGAiEA4IWSoxe3jfkrBqWTrBqYaGFy+uGh0Psc -eGCmQ5nFuMQCIQCcAu/xlJyzlvnrxir4tiz+OpAUFteMYyRIHN8wfdVoOw== ------END CERTIFICATE----- - -Amazon Root CA 4 -================ ------BEGIN CERTIFICATE----- -MIIB8jCCAXigAwIBAgITBmyf18G7EEwpQ+Vxe3ssyBrBDjAKBggqhkjOPQQDAzA5MQswCQYDVQQG -EwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24gUm9vdCBDQSA0MB4XDTE1MDUy -NjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZ -MBcGA1UEAxMQQW1hem9uIFJvb3QgQ0EgNDB2MBAGByqGSM49AgEGBSuBBAAiA2IABNKrijdPo1MN -/sGKe0uoe0ZLY7Bi9i0b2whxIdIA6GO9mif78DluXeo9pcmBqqNbIJhFXRbb/egQbeOc4OO9X4Ri -83BkM6DLJC9wuoihKqB1+IGuYgbEgds5bimwHvouXKNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNV -HQ8BAf8EBAMCAYYwHQYDVR0OBBYEFNPsxzplbszh2naaVvuc84ZtV+WBMAoGCCqGSM49BAMDA2gA -MGUCMDqLIfG9fhGt0O9Yli/W651+kI0rz2ZVwyzjKKlwCkcO8DdZEv8tmZQoTipPNU0zWgIxAOp1 -AE47xDqUEpHJWEadIRNyp4iciuRMStuW1KyLa2tJElMzrdfkviT8tQp21KW8EA== ------END CERTIFICATE----- - -TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1 -============================================= ------BEGIN CERTIFICATE----- -MIIEYzCCA0ugAwIBAgIBATANBgkqhkiG9w0BAQsFADCB0jELMAkGA1UEBhMCVFIxGDAWBgNVBAcT -D0dlYnplIC0gS29jYWVsaTFCMEAGA1UEChM5VHVya2l5ZSBCaWxpbXNlbCB2ZSBUZWtub2xvamlr -IEFyYXN0aXJtYSBLdXJ1bXUgLSBUVUJJVEFLMS0wKwYDVQQLEyRLYW11IFNlcnRpZmlrYXN5b24g -TWVya2V6aSAtIEthbXUgU00xNjA0BgNVBAMTLVRVQklUQUsgS2FtdSBTTSBTU0wgS29rIFNlcnRp -ZmlrYXNpIC0gU3VydW0gMTAeFw0xMzExMjUwODI1NTVaFw00MzEwMjUwODI1NTVaMIHSMQswCQYD -VQQGEwJUUjEYMBYGA1UEBxMPR2ViemUgLSBLb2NhZWxpMUIwQAYDVQQKEzlUdXJraXllIEJpbGlt -c2VsIHZlIFRla25vbG9qaWsgQXJhc3Rpcm1hIEt1cnVtdSAtIFRVQklUQUsxLTArBgNVBAsTJEth -bXUgU2VydGlmaWthc3lvbiBNZXJrZXppIC0gS2FtdSBTTTE2MDQGA1UEAxMtVFVCSVRBSyBLYW11 -IFNNIFNTTCBLb2sgU2VydGlmaWthc2kgLSBTdXJ1bSAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A -MIIBCgKCAQEAr3UwM6q7a9OZLBI3hNmNe5eA027n/5tQlT6QlVZC1xl8JoSNkvoBHToP4mQ4t4y8 -6Ij5iySrLqP1N+RAjhgleYN1Hzv/bKjFxlb4tO2KRKOrbEz8HdDc72i9z+SqzvBV96I01INrN3wc -wv61A+xXzry0tcXtAA9TNypN9E8Mg/uGz8v+jE69h/mniyFXnHrfA2eJLJ2XYacQuFWQfw4tJzh0 -3+f92k4S400VIgLI4OD8D62K18lUUMw7D8oWgITQUVbDjlZ/iSIzL+aFCr2lqBs23tPcLG07xxO9 -WSMs5uWk99gL7eqQQESolbuT1dCANLZGeA4fAJNG4e7p+exPFwIDAQABo0IwQDAdBgNVHQ4EFgQU -ZT/HiobGPN08VFw1+DrtUgxHV8gwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJ -KoZIhvcNAQELBQADggEBACo/4fEyjq7hmFxLXs9rHmoJ0iKpEsdeV31zVmSAhHqT5Am5EM2fKifh -AHe+SMg1qIGf5LgsyX8OsNJLN13qudULXjS99HMpw+0mFZx+CFOKWI3QSyjfwbPfIPP54+M638yc -lNhOT8NrF7f3cuitZjO1JVOr4PhMqZ398g26rrnZqsZr+ZO7rqu4lzwDGrpDxpa5RXI4s6ehlj2R -e37AIVNMh+3yC1SVUZPVIqUNivGTDj5UDrDYyU7c8jEyVupk+eq1nRZmQnLzf9OxMUP8pI4X8W0j -q5Rm+K37DwhuJi1/FwcJsoz7UMCflo3Ptv0AnVoUmr8CRPXBwp8iXqIPoeM= ------END CERTIFICATE----- - -GDCA TrustAUTH R5 ROOT -====================== ------BEGIN CERTIFICATE----- -MIIFiDCCA3CgAwIBAgIIfQmX/vBH6nowDQYJKoZIhvcNAQELBQAwYjELMAkGA1UEBhMCQ04xMjAw -BgNVBAoMKUdVQU5HIERPTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZIENPLixMVEQuMR8wHQYDVQQD -DBZHRENBIFRydXN0QVVUSCBSNSBST09UMB4XDTE0MTEyNjA1MTMxNVoXDTQwMTIzMTE1NTk1OVow -YjELMAkGA1UEBhMCQ04xMjAwBgNVBAoMKUdVQU5HIERPTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZ -IENPLixMVEQuMR8wHQYDVQQDDBZHRENBIFRydXN0QVVUSCBSNSBST09UMIICIjANBgkqhkiG9w0B -AQEFAAOCAg8AMIICCgKCAgEA2aMW8Mh0dHeb7zMNOwZ+Vfy1YI92hhJCfVZmPoiC7XJjDp6L3TQs -AlFRwxn9WVSEyfFrs0yw6ehGXTjGoqcuEVe6ghWinI9tsJlKCvLriXBjTnnEt1u9ol2x8kECK62p -OqPseQrsXzrj/e+APK00mxqriCZ7VqKChh/rNYmDf1+uKU49tm7srsHwJ5uu4/Ts765/94Y9cnrr -pftZTqfrlYwiOXnhLQiPzLyRuEH3FMEjqcOtmkVEs7LXLM3GKeJQEK5cy4KOFxg2fZfmiJqwTTQJ -9Cy5WmYqsBebnh52nUpmMUHfP/vFBu8btn4aRjb3ZGM74zkYI+dndRTVdVeSN72+ahsmUPI2JgaQ -xXABZG12ZuGR224HwGGALrIuL4xwp9E7PLOR5G62xDtw8mySlwnNR30YwPO7ng/Wi64HtloPzgsM -R6flPri9fcebNaBhlzpBdRfMK5Z3KpIhHtmVdiBnaM8Nvd/WHwlqmuLMc3GkL30SgLdTMEZeS1SZ -D2fJpcjyIMGC7J0R38IC+xo70e0gmu9lZJIQDSri3nDxGGeCjGHeuLzRL5z7D9Ar7Rt2ueQ5Vfj4 -oR24qoAATILnsn8JuLwwoC8N9VKejveSswoAHQBUlwbgsQfZxw9cZX08bVlX5O2ljelAU58VS6Bx -9hoh49pwBiFYFIeFd3mqgnkCAwEAAaNCMEAwHQYDVR0OBBYEFOLJQJ9NzuiaoXzPDj9lxSmIahlR -MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQDRSVfg -p8xoWLoBDysZzY2wYUWsEe1jUGn4H3++Fo/9nesLqjJHdtJnJO29fDMylyrHBYZmDRd9FBUb1Ov9 -H5r2XpdptxolpAqzkT9fNqyL7FeoPueBihhXOYV0GkLH6VsTX4/5COmSdI31R9KrO9b7eGZONn35 -6ZLpBN79SWP8bfsUcZNnL0dKt7n/HipzcEYwv1ryL3ml4Y0M2fmyYzeMN2WFcGpcWwlyua1jPLHd -+PwyvzeG5LuOmCd+uh8W4XAR8gPfJWIyJyYYMoSf/wA6E7qaTfRPuBRwIrHKK5DOKcFw9C+df/KQ -HtZa37dG/OaG+svgIHZ6uqbL9XzeYqWxi+7egmaKTjowHz+Ay60nugxe19CxVsp3cbK1daFQqUBD -F8Io2c9Si1vIY9RCPqAzekYu9wogRlR+ak8x8YF+QnQ4ZXMn7sZ8uI7XpTrXmKGcjBBV09tL7ECQ -8s1uV9JiDnxXk7Gnbc2dg7sq5+W2O3FYrf3RRbxake5TFW/TRQl1brqQXR4EzzffHqhmsYzmIGrv -/EhOdJhCrylvLmrH+33RZjEizIYAfmaDDEL0vTSSwxrqT8p+ck0LcIymSLumoRT2+1hEmRSuqguT -aaApJUqlyyvdimYHFngVV3Eb7PVHhPOeMTd61X8kreS8/f3MboPoDKi3QWwH3b08hpcv0g== ------END CERTIFICATE----- - -SSL.com Root Certification Authority RSA -======================================== ------BEGIN CERTIFICATE----- -MIIF3TCCA8WgAwIBAgIIeyyb0xaAMpkwDQYJKoZIhvcNAQELBQAwfDELMAkGA1UEBhMCVVMxDjAM -BgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9TU0wgQ29ycG9yYXRpb24x -MTAvBgNVBAMMKFNTTC5jb20gUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSBSU0EwHhcNMTYw -MjEyMTczOTM5WhcNNDEwMjEyMTczOTM5WjB8MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMx -EDAOBgNVBAcMB0hvdXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjExMC8GA1UEAwwoU1NM -LmNvbSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IFJTQTCCAiIwDQYJKoZIhvcNAQEBBQAD -ggIPADCCAgoCggIBAPkP3aMrfcvQKv7sZ4Wm5y4bunfh4/WvpOz6Sl2RxFdHaxh3a3by/ZPkPQ/C -Fp4LZsNWlJ4Xg4XOVu/yFv0AYvUiCVToZRdOQbngT0aXqhvIuG5iXmmxX9sqAn78bMrzQdjt0Oj8 -P2FI7bADFB0QDksZ4LtO7IZl/zbzXmcCC52GVWH9ejjt/uIZALdvoVBidXQ8oPrIJZK0bnoix/ge -oeOy3ZExqysdBP+lSgQ36YWkMyv94tZVNHwZpEpox7Ko07fKoZOI68GXvIz5HdkihCR0xwQ9aqkp -k8zruFvh/l8lqjRYyMEjVJ0bmBHDOJx+PYZspQ9AhnwC9FwCTyjLrnGfDzrIM/4RJTXq/LrFYD3Z -fBjVsqnTdXgDciLKOsMf7yzlLqn6niy2UUb9rwPW6mBo6oUWNmuF6R7As93EJNyAKoFBbZQ+yODJ -gUEAnl6/f8UImKIYLEJAs/lvOCdLToD0PYFH4Ih86hzOtXVcUS4cK38acijnALXRdMbX5J+tB5O2 -UzU1/Dfkw/ZdFr4hc96SCvigY2q8lpJqPvi8ZVWb3vUNiSYE/CUapiVpy8JtynziWV+XrOvvLsi8 -1xtZPCvM8hnIk2snYxnP/Okm+Mpxm3+T/jRnhE6Z6/yzeAkzcLpmpnbtG3PrGqUNxCITIJRWCk4s -bE6x/c+cCbqiM+2HAgMBAAGjYzBhMB0GA1UdDgQWBBTdBAkHovV6fVJTEpKV7jiAJQ2mWTAPBgNV -HRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFN0ECQei9Xp9UlMSkpXuOIAlDaZZMA4GA1UdDwEB/wQE -AwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAIBgRlCn7Jp0cHh5wYfGVcpNxJK1ok1iOMq8bs3AD/CUr -dIWQPXhq9LmLpZc7tRiRux6n+UBbkflVma8eEdBcHadm47GUBwwyOabqG7B52B2ccETjit3E+ZUf -ijhDPwGFpUenPUayvOUiaPd7nNgsPgohyC0zrL/FgZkxdMF1ccW+sfAjRfSda/wZY52jvATGGAsl -u1OJD7OAUN5F7kR/q5R4ZJjT9ijdh9hwZXT7DrkT66cPYakylszeu+1jTBi7qUD3oFRuIIhxdRjq -erQ0cuAjJ3dctpDqhiVAq+8zD8ufgr6iIPv2tS0a5sKFsXQP+8hlAqRSAUfdSSLBv9jra6x+3uxj -MxW3IwiPxg+NQVrdjsW5j+VFP3jbutIbQLH+cU0/4IGiul607BXgk90IH37hVZkLId6Tngr75qNJ -vTYw/ud3sqB1l7UtgYgXZSD32pAAn8lSzDLKNXz1PQ/YK9f1JmzJBjSWFupwWRoyeXkLtoh/D1JI -Pb9s2KJELtFOt3JY04kTlf5Eq/jXixtunLwsoFvVagCvXzfh1foQC5ichucmj87w7G6KVwuA406y -wKBjYZC6VWg3dGq2ktufoYYitmUnDuy2n0Jg5GfCtdpBC8TTi2EbvPofkSvXRAdeuims2cXp71NI -WuuA8ShYIc2wBlX7Jz9TkHCpBB5XJ7k= ------END CERTIFICATE----- - -SSL.com Root Certification Authority ECC -======================================== ------BEGIN CERTIFICATE----- -MIICjTCCAhSgAwIBAgIIdebfy8FoW6gwCgYIKoZIzj0EAwIwfDELMAkGA1UEBhMCVVMxDjAMBgNV -BAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9TU0wgQ29ycG9yYXRpb24xMTAv -BgNVBAMMKFNTTC5jb20gUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSBFQ0MwHhcNMTYwMjEy -MTgxNDAzWhcNNDEwMjEyMTgxNDAzWjB8MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAO -BgNVBAcMB0hvdXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjExMC8GA1UEAwwoU1NMLmNv -bSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQzB2MBAGByqGSM49AgEGBSuBBAAiA2IA -BEVuqVDEpiM2nl8ojRfLliJkP9x6jh3MCLOicSS6jkm5BBtHllirLZXI7Z4INcgn64mMU1jrYor+ -8FsPazFSY0E7ic3s7LaNGdM0B9y7xgZ/wkWV7Mt/qCPgCemB+vNH06NjMGEwHQYDVR0OBBYEFILR -hXMw5zUE044CkvvlpNHEIejNMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUgtGFczDnNQTT -jgKS++Wk0cQh6M0wDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2cAMGQCMG/n61kRpGDPYbCW -e+0F+S8Tkdzt5fxQaxFGRrMcIQBiu77D5+jNB5n5DQtdcj7EqgIwH7y6C+IwJPt8bYBVCpk+gA0z -5Wajs6O7pdWLjwkspl1+4vAHCGht0nxpbl/f5Wpl ------END CERTIFICATE----- - -SSL.com EV Root Certification Authority RSA R2 -============================================== ------BEGIN CERTIFICATE----- -MIIF6zCCA9OgAwIBAgIIVrYpzTS8ePYwDQYJKoZIhvcNAQELBQAwgYIxCzAJBgNVBAYTAlVTMQ4w -DAYDVQQIDAVUZXhhczEQMA4GA1UEBwwHSG91c3RvbjEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9u -MTcwNQYDVQQDDC5TU0wuY29tIEVWIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgUlNBIFIy -MB4XDTE3MDUzMTE4MTQzN1oXDTQyMDUzMDE4MTQzN1owgYIxCzAJBgNVBAYTAlVTMQ4wDAYDVQQI -DAVUZXhhczEQMA4GA1UEBwwHSG91c3RvbjEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMTcwNQYD -VQQDDC5TU0wuY29tIEVWIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgUlNBIFIyMIICIjAN -BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAjzZlQOHWTcDXtOlG2mvqM0fNTPl9fb69LT3w23jh -hqXZuglXaO1XPqDQCEGD5yhBJB/jchXQARr7XnAjssufOePPxU7Gkm0mxnu7s9onnQqG6YE3Bf7w -cXHswxzpY6IXFJ3vG2fThVUCAtZJycxa4bH3bzKfydQ7iEGonL3Lq9ttewkfokxykNorCPzPPFTO -Zw+oz12WGQvE43LrrdF9HSfvkusQv1vrO6/PgN3B0pYEW3p+pKk8OHakYo6gOV7qd89dAFmPZiw+ -B6KjBSYRaZfqhbcPlgtLyEDhULouisv3D5oi53+aNxPN8k0TayHRwMwi8qFG9kRpnMphNQcAb9Zh -CBHqurj26bNg5U257J8UZslXWNvNh2n4ioYSA0e/ZhN2rHd9NCSFg83XqpyQGp8hLH94t2S42Oim -9HizVcuE0jLEeK6jj2HdzghTreyI/BXkmg3mnxp3zkyPuBQVPWKchjgGAGYS5Fl2WlPAApiiECto -RHuOec4zSnaqW4EWG7WK2NAAe15itAnWhmMOpgWVSbooi4iTsjQc2KRVbrcc0N6ZVTsj9CLg+Slm -JuwgUHfbSguPvuUCYHBBXtSuUDkiFCbLsjtzdFVHB3mBOagwE0TlBIqulhMlQg+5U8Sb/M3kHN48 -+qvWBkofZ6aYMBzdLNvcGJVXZsb/XItW9XcCAwEAAaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAfBgNV -HSMEGDAWgBT5YLvU49U09rj1BoAlp3PbRmmonjAdBgNVHQ4EFgQU+WC71OPVNPa49QaAJadz20Zp -qJ4wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQBWs47LCp1Jjr+kxJG7ZhcFUZh1 -++VQLHqe8RT6q9OKPv+RKY9ji9i0qVQBDb6Thi/5Sm3HXvVX+cpVHBK+Rw82xd9qt9t1wkclf7nx -Y/hoLVUE0fKNsKTPvDxeH3jnpaAgcLAExbf3cqfeIg29MyVGjGSSJuM+LmOW2puMPfgYCdcDzH2G -guDKBAdRUNf/ktUM79qGn5nX67evaOI5JpS6aLe/g9Pqemc9YmeuJeVy6OLk7K4S9ksrPJ/psEDz -OFSz/bdoyNrGj1E8svuR3Bznm53htw1yj+KkxKl4+esUrMZDBcJlOSgYAsOCsp0FvmXtll9ldDz7 -CTUue5wT/RsPXcdtgTpWD8w74a8CLyKsRspGPKAcTNZEtF4uXBVmCeEmKf7GUmG6sXP/wwyc5Wxq -lD8UykAWlYTzWamsX0xhk23RO8yilQwipmdnRC652dKKQbNmC1r7fSOl8hqw/96bg5Qu0T/fkreR -rwU7ZcegbLHNYhLDkBvjJc40vG93drEQw/cFGsDWr3RiSBd3kmmQYRzelYB0VI8YHMPzA9C/pEN1 -hlMYegouCRw2n5H9gooiS9EOUCXdywMMF8mDAAhONU2Ki+3wApRmLER/y5UnlhetCTCstnEXbosX -9hwJ1C07mKVx01QT2WDz9UtmT/rx7iASjbSsV7FFY6GsdqnC+w== ------END CERTIFICATE----- - -SSL.com EV Root Certification Authority ECC -=========================================== ------BEGIN CERTIFICATE----- -MIIClDCCAhqgAwIBAgIILCmcWxbtBZUwCgYIKoZIzj0EAwIwfzELMAkGA1UEBhMCVVMxDjAMBgNV -BAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9TU0wgQ29ycG9yYXRpb24xNDAy -BgNVBAMMK1NTTC5jb20gRVYgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSBFQ0MwHhcNMTYw -MjEyMTgxNTIzWhcNNDEwMjEyMTgxNTIzWjB/MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMx -EDAOBgNVBAcMB0hvdXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjE0MDIGA1UEAwwrU1NM -LmNvbSBFViBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQzB2MBAGByqGSM49AgEGBSuB -BAAiA2IABKoSR5CYG/vvw0AHgyBO8TCCogbR8pKGYfL2IWjKAMTH6kMAVIbc/R/fALhBYlzccBYy -3h+Z1MzFB8gIH2EWB1E9fVwHU+M1OIzfzZ/ZLg1KthkuWnBaBu2+8KGwytAJKaNjMGEwHQYDVR0O -BBYEFFvKXuXe0oGqzagtZFG22XKbl+ZPMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUW8pe -5d7SgarNqC1kUbbZcpuX5k8wDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2gAMGUCMQCK5kCJ -N+vp1RPZytRrJPOwPYdGWBrssd9v+1a6cGvHOMzosYxPD/fxZ3YOg9AeUY8CMD32IygmTMZgh5Mm -m7I1HrrW9zzRHM76JTymGoEVW/MSD2zuZYrJh6j5B+BimoxcSg== ------END CERTIFICATE----- - -GlobalSign Root CA - R6 -======================= ------BEGIN CERTIFICATE----- -MIIFgzCCA2ugAwIBAgIORea7A4Mzw4VlSOb/RVEwDQYJKoZIhvcNAQEMBQAwTDEgMB4GA1UECxMX -R2xvYmFsU2lnbiBSb290IENBIC0gUjYxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkds -b2JhbFNpZ24wHhcNMTQxMjEwMDAwMDAwWhcNMzQxMjEwMDAwMDAwWjBMMSAwHgYDVQQLExdHbG9i -YWxTaWduIFJvb3QgQ0EgLSBSNjETMBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFs -U2lnbjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAJUH6HPKZvnsFMp7PPcNCPG0RQss -grRIxutbPK6DuEGSMxSkb3/pKszGsIhrxbaJ0cay/xTOURQh7ErdG1rG1ofuTToVBu1kZguSgMpE -3nOUTvOniX9PeGMIyBJQbUJmL025eShNUhqKGoC3GYEOfsSKvGRMIRxDaNc9PIrFsmbVkJq3MQbF -vuJtMgamHvm566qjuL++gmNQ0PAYid/kD3n16qIfKtJwLnvnvJO7bVPiSHyMEAc4/2ayd2F+4OqM -PKq0pPbzlUoSB239jLKJz9CgYXfIWHSw1CM69106yqLbnQneXUQtkPGBzVeS+n68UARjNN9rkxi+ -azayOeSsJDa38O+2HBNXk7besvjihbdzorg1qkXy4J02oW9UivFyVm4uiMVRQkQVlO6jxTiWm05O -WgtH8wY2SXcwvHE35absIQh1/OZhFj931dmRl4QKbNQCTXTAFO39OfuD8l4UoQSwC+n+7o/hbguy -CLNhZglqsQY6ZZZZwPA1/cnaKI0aEYdwgQqomnUdnjqGBQCe24DWJfncBZ4nWUx2OVvq+aWh2IMP -0f/fMBH5hc8zSPXKbWQULHpYT9NLCEnFlWQaYw55PfWzjMpYrZxCRXluDocZXFSxZba/jJvcE+kN -b7gu3GduyYsRtYQUigAZcIN5kZeR1BonvzceMgfYFGM8KEyvAgMBAAGjYzBhMA4GA1UdDwEB/wQE -AwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSubAWjkxPioufi1xzWx/B/yGdToDAfBgNV -HSMEGDAWgBSubAWjkxPioufi1xzWx/B/yGdToDANBgkqhkiG9w0BAQwFAAOCAgEAgyXt6NH9lVLN -nsAEoJFp5lzQhN7craJP6Ed41mWYqVuoPId8AorRbrcWc+ZfwFSY1XS+wc3iEZGtIxg93eFyRJa0 -lV7Ae46ZeBZDE1ZXs6KzO7V33EByrKPrmzU+sQghoefEQzd5Mr6155wsTLxDKZmOMNOsIeDjHfrY -BzN2VAAiKrlNIC5waNrlU/yDXNOd8v9EDERm8tLjvUYAGm0CuiVdjaExUd1URhxN25mW7xocBFym -Fe944Hn+Xds+qkxV/ZoVqW/hpvvfcDDpw+5CRu3CkwWJ+n1jez/QcYF8AOiYrg54NMMl+68KnyBr -3TsTjxKM4kEaSHpzoHdpx7Zcf4LIHv5YGygrqGytXm3ABdJ7t+uA/iU3/gKbaKxCXcPu9czc8FB1 -0jZpnOZ7BN9uBmm23goJSFmH63sUYHpkqmlD75HHTOwY3WzvUy2MmeFe8nI+z1TIvWfspA9MRf/T -uTAjB0yPEL+GltmZWrSZVxykzLsViVO6LAUP5MSeGbEYNNVMnbrt9x+vJJUEeKgDu+6B5dpffItK -oZB0JaezPkvILFa9x8jvOOJckvB595yEunQtYQEgfn7R8k8HWV+LLUNS60YMlOH1Zkd5d9VUWx+t -JDfLRVpOoERIyNiwmcUVhAn21klJwGW45hpxbqCo8YLoRT5s1gLXCmeDBVrJpBA= ------END CERTIFICATE----- - -OISTE WISeKey Global Root GC CA -=============================== ------BEGIN CERTIFICATE----- -MIICaTCCAe+gAwIBAgIQISpWDK7aDKtARb8roi066jAKBggqhkjOPQQDAzBtMQswCQYDVQQGEwJD -SDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUgRm91bmRhdGlvbiBFbmRvcnNlZDEo -MCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9iYWwgUm9vdCBHQyBDQTAeFw0xNzA1MDkwOTQ4MzRa -Fw00MjA1MDkwOTU4MzNaMG0xCzAJBgNVBAYTAkNIMRAwDgYDVQQKEwdXSVNlS2V5MSIwIAYDVQQL -ExlPSVNURSBGb3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5IEdsb2Jh -bCBSb290IEdDIENBMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAETOlQwMYPchi82PG6s4nieUqjFqdr -VCTbUf/q9Akkwwsin8tqJ4KBDdLArzHkdIJuyiXZjHWd8dvQmqJLIX4Wp2OQ0jnUsYd4XxiWD1Ab -NTcPasbc2RNNpI6QN+a9WzGRo1QwUjAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAd -BgNVHQ4EFgQUSIcUrOPDnpBgOtfKie7TrYy0UGYwEAYJKwYBBAGCNxUBBAMCAQAwCgYIKoZIzj0E -AwMDaAAwZQIwJsdpW9zV57LnyAyMjMPdeYwbY9XJUpROTYJKcx6ygISpJcBMWm1JKWB4E+J+SOtk -AjEA2zQgMgj/mkkCtojeFK9dbJlxjRo/i9fgojaGHAeCOnZT/cKi7e97sIBPWA9LUzm9 ------END CERTIFICATE----- - -UCA Global G2 Root -================== ------BEGIN CERTIFICATE----- -MIIFRjCCAy6gAwIBAgIQXd+x2lqj7V2+WmUgZQOQ7zANBgkqhkiG9w0BAQsFADA9MQswCQYDVQQG -EwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxGzAZBgNVBAMMElVDQSBHbG9iYWwgRzIgUm9vdDAeFw0x -NjAzMTEwMDAwMDBaFw00MDEyMzEwMDAwMDBaMD0xCzAJBgNVBAYTAkNOMREwDwYDVQQKDAhVbmlU -cnVzdDEbMBkGA1UEAwwSVUNBIEdsb2JhbCBHMiBSb290MIICIjANBgkqhkiG9w0BAQEFAAOCAg8A -MIICCgKCAgEAxeYrb3zvJgUno4Ek2m/LAfmZmqkywiKHYUGRO8vDaBsGxUypK8FnFyIdK+35KYmT -oni9kmugow2ifsqTs6bRjDXVdfkX9s9FxeV67HeToI8jrg4aA3++1NDtLnurRiNb/yzmVHqUwCoV -8MmNsHo7JOHXaOIxPAYzRrZUEaalLyJUKlgNAQLx+hVRZ2zA+te2G3/RVogvGjqNO7uCEeBHANBS -h6v7hn4PJGtAnTRnvI3HLYZveT6OqTwXS3+wmeOwcWDcC/Vkw85DvG1xudLeJ1uK6NjGruFZfc8o -LTW4lVYa8bJYS7cSN8h8s+1LgOGN+jIjtm+3SJUIsUROhYw6AlQgL9+/V087OpAh18EmNVQg7Mc/ -R+zvWr9LesGtOxdQXGLYD0tK3Cv6brxzks3sx1DoQZbXqX5t2Okdj4q1uViSukqSKwxW/YDrCPBe -KW4bHAyvj5OJrdu9o54hyokZ7N+1wxrrFv54NkzWbtA+FxyQF2smuvt6L78RHBgOLXMDj6DlNaBa -4kx1HXHhOThTeEDMg5PXCp6dW4+K5OXgSORIskfNTip1KnvyIvbJvgmRlld6iIis7nCs+dwp4wwc -OxJORNanTrAmyPPZGpeRaOrvjUYG0lZFWJo8DA+DuAUlwznPO6Q0ibd5Ei9Hxeepl2n8pndntd97 -8XplFeRhVmUCAwEAAaNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0O -BBYEFIHEjMz15DD/pQwIX4wVZyF0Ad/fMA0GCSqGSIb3DQEBCwUAA4ICAQATZSL1jiutROTL/7lo -5sOASD0Ee/ojL3rtNtqyzm325p7lX1iPyzcyochltq44PTUbPrw7tgTQvPlJ9Zv3hcU2tsu8+Mg5 -1eRfB70VVJd0ysrtT7q6ZHafgbiERUlMjW+i67HM0cOU2kTC5uLqGOiiHycFutfl1qnN3e92mI0A -Ds0b+gO3joBYDic/UvuUospeZcnWhNq5NXHzJsBPd+aBJ9J3O5oUb3n09tDh05S60FdRvScFDcH9 -yBIw7m+NESsIndTUv4BFFJqIRNow6rSn4+7vW4LVPtateJLbXDzz2K36uGt/xDYotgIVilQsnLAX -c47QN6MUPJiVAAwpBVueSUmxX8fjy88nZY41F7dXyDDZQVu5FLbowg+UMaeUmMxq67XhJ/UQqAHo -jhJi6IjMtX9Gl8CbEGY4GjZGXyJoPd/JxhMnq1MGrKI8hgZlb7F+sSlEmqO6SWkoaY/X5V+tBIZk -bxqgDMUIYs6Ao9Dz7GjevjPHF1t/gMRMTLGmhIrDO7gJzRSBuhjjVFc2/tsvfEehOjPI+Vg7RE+x -ygKJBJYoaMVLuCaJu9YzL1DV/pqJuhgyklTGW+Cd+V7lDSKb9triyCGyYiGqhkCyLmTTX8jjfhFn -RR8F/uOi77Oos/N9j/gMHyIfLXC0uAE0djAA5SN4p1bXUB+K+wb1whnw0A== ------END CERTIFICATE----- - -UCA Extended Validation Root -============================ ------BEGIN CERTIFICATE----- -MIIFWjCCA0KgAwIBAgIQT9Irj/VkyDOeTzRYZiNwYDANBgkqhkiG9w0BAQsFADBHMQswCQYDVQQG -EwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxJTAjBgNVBAMMHFVDQSBFeHRlbmRlZCBWYWxpZGF0aW9u -IFJvb3QwHhcNMTUwMzEzMDAwMDAwWhcNMzgxMjMxMDAwMDAwWjBHMQswCQYDVQQGEwJDTjERMA8G -A1UECgwIVW5pVHJ1c3QxJTAjBgNVBAMMHFVDQSBFeHRlbmRlZCBWYWxpZGF0aW9uIFJvb3QwggIi -MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCpCQcoEwKwmeBkqh5DFnpzsZGgdT6o+uM4AHrs -iWogD4vFsJszA1qGxliG1cGFu0/GnEBNyr7uaZa4rYEwmnySBesFK5pI0Lh2PpbIILvSsPGP2KxF -Rv+qZ2C0d35qHzwaUnoEPQc8hQ2E0B92CvdqFN9y4zR8V05WAT558aopO2z6+I9tTcg1367r3CTu -eUWnhbYFiN6IXSV8l2RnCdm/WhUFhvMJHuxYMjMR83dksHYf5BA1FxvyDrFspCqjc/wJHx4yGVMR -59mzLC52LqGj3n5qiAno8geK+LLNEOfic0CTuwjRP+H8C5SzJe98ptfRr5//lpr1kXuYC3fUfugH -0mK1lTnj8/FtDw5lhIpjVMWAtuCeS31HJqcBCF3RiJ7XwzJE+oJKCmhUfzhTA8ykADNkUVkLo4KR -el7sFsLzKuZi2irbWWIQJUoqgQtHB0MGcIfS+pMRKXpITeuUx3BNr2fVUbGAIAEBtHoIppB/TuDv -B0GHr2qlXov7z1CymlSvw4m6WC31MJixNnI5fkkE/SmnTHnkBVfblLkWU41Gsx2VYVdWf6/wFlth -WG82UBEL2KwrlRYaDh8IzTY0ZRBiZtWAXxQgXy0MoHgKaNYs1+lvK9JKBZP8nm9rZ/+I8U6laUpS -NwXqxhaN0sSZ0YIrO7o1dfdRUVjzyAfd5LQDfwIDAQABo0IwQDAdBgNVHQ4EFgQU2XQ65DA9DfcS -3H5aBZ8eNJr34RQwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQEL -BQADggIBADaNl8xCFWQpN5smLNb7rhVpLGsaGvdftvkHTFnq88nIua7Mui563MD1sC3AO6+fcAUR -ap8lTwEpcOPlDOHqWnzcSbvBHiqB9RZLcpHIojG5qtr8nR/zXUACE/xOHAbKsxSQVBcZEhrxH9cM -aVr2cXj0lH2RC47skFSOvG+hTKv8dGT9cZr4QQehzZHkPJrgmzI5c6sq1WnIeJEmMX3ixzDx/BR4 -dxIOE/TdFpS/S2d7cFOFyrC78zhNLJA5wA3CXWvp4uXViI3WLL+rG761KIcSF3Ru/H38j9CHJrAb -+7lsq+KePRXBOy5nAliRn+/4Qh8st2j1da3Ptfb/EX3C8CSlrdP6oDyp+l3cpaDvRKS+1ujl5BOW -F3sGPjLtx7dCvHaj2GU4Kzg1USEODm8uNBNA4StnDG1KQTAYI1oyVZnJF+A83vbsea0rWBmirSwi -GpWOvpaQXUJXxPkUAzUrHC1RVwinOt4/5Mi0A3PCwSaAuwtCH60NryZy2sy+s6ODWA2CxR9GUeOc -GMyNm43sSet1UNWMKFnKdDTajAshqx7qG+XH/RU+wBeq+yNuJkbL+vmxcmtpzyKEC2IPrNkZAJSi -djzULZrtBJ4tBmIQN1IchXIbJ+XMxjHsN+xjWZsLHXbMfjKaiJUINlK73nZfdklJrX+9ZSCyycEr -dhh2n1ax ------END CERTIFICATE----- - -Certigna Root CA -================ ------BEGIN CERTIFICATE----- -MIIGWzCCBEOgAwIBAgIRAMrpG4nxVQMNo+ZBbcTjpuEwDQYJKoZIhvcNAQELBQAwWjELMAkGA1UE -BhMCRlIxEjAQBgNVBAoMCURoaW15b3RpczEcMBoGA1UECwwTMDAwMiA0ODE0NjMwODEwMDAzNjEZ -MBcGA1UEAwwQQ2VydGlnbmEgUm9vdCBDQTAeFw0xMzEwMDEwODMyMjdaFw0zMzEwMDEwODMyMjda -MFoxCzAJBgNVBAYTAkZSMRIwEAYDVQQKDAlEaGlteW90aXMxHDAaBgNVBAsMEzAwMDIgNDgxNDYz -MDgxMDAwMzYxGTAXBgNVBAMMEENlcnRpZ25hIFJvb3QgQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4IC -DwAwggIKAoICAQDNGDllGlmx6mQWDoyUJJV8g9PFOSbcDO8WV43X2KyjQn+Cyu3NW9sOty3tRQgX -stmzy9YXUnIo245Onoq2C/mehJpNdt4iKVzSs9IGPjA5qXSjklYcoW9MCiBtnyN6tMbaLOQdLNyz -KNAT8kxOAkmhVECe5uUFoC2EyP+YbNDrihqECB63aCPuI9Vwzm1RaRDuoXrC0SIxwoKF0vJVdlB8 -JXrJhFwLrN1CTivngqIkicuQstDuI7pmTLtipPlTWmR7fJj6o0ieD5Wupxj0auwuA0Wv8HT4Ks16 -XdG+RCYyKfHx9WzMfgIhC59vpD++nVPiz32pLHxYGpfhPTc3GGYo0kDFUYqMwy3OU4gkWGQwFsWq -4NYKpkDfePb1BHxpE4S80dGnBs8B92jAqFe7OmGtBIyT46388NtEbVncSVmurJqZNjBBe3YzIoej -wpKGbvlw7q6Hh5UbxHq9MfPU0uWZ/75I7HX1eBYdpnDBfzwboZL7z8g81sWTCo/1VTp2lc5ZmIoJ -lXcymoO6LAQ6l73UL77XbJuiyn1tJslV1c/DeVIICZkHJC1kJWumIWmbat10TWuXekG9qxf5kBdI -jzb5LdXF2+6qhUVB+s06RbFo5jZMm5BX7CO5hwjCxAnxl4YqKE3idMDaxIzb3+KhF1nOJFl0Mdp/ -/TBt2dzhauH8XwIDAQABo4IBGjCCARYwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYw -HQYDVR0OBBYEFBiHVuBud+4kNTxOc5of1uHieX4rMB8GA1UdIwQYMBaAFBiHVuBud+4kNTxOc5of -1uHieX4rMEQGA1UdIAQ9MDswOQYEVR0gADAxMC8GCCsGAQUFBwIBFiNodHRwczovL3d3d3cuY2Vy -dGlnbmEuZnIvYXV0b3JpdGVzLzBtBgNVHR8EZjBkMC+gLaArhilodHRwOi8vY3JsLmNlcnRpZ25h -LmZyL2NlcnRpZ25hcm9vdGNhLmNybDAxoC+gLYYraHR0cDovL2NybC5kaGlteW90aXMuY29tL2Nl -cnRpZ25hcm9vdGNhLmNybDANBgkqhkiG9w0BAQsFAAOCAgEAlLieT/DjlQgi581oQfccVdV8AOIt -OoldaDgvUSILSo3L6btdPrtcPbEo/uRTVRPPoZAbAh1fZkYJMyjhDSSXcNMQH+pkV5a7XdrnxIxP -TGRGHVyH41neQtGbqH6mid2PHMkwgu07nM3A6RngatgCdTer9zQoKJHyBApPNeNgJgH60BGM+RFq -7q89w1DTj18zeTyGqHNFkIwgtnJzFyO+B2XleJINugHA64wcZr+shncBlA2c5uk5jR+mUYyZDDl3 -4bSb+hxnV29qao6pK0xXeXpXIs/NX2NGjVxZOob4Mkdio2cNGJHc+6Zr9UhhcyNZjgKnvETq9Emd -8VRY+WCv2hikLyhF3HqgiIZd8zvn/yk1gPxkQ5Tm4xxvvq0OKmOZK8l+hfZx6AYDlf7ej0gcWtSS -6Cvu5zHbugRqh5jnxV/vfaci9wHYTfmJ0A6aBVmknpjZbyvKcL5kwlWj9Omvw5Ip3IgWJJk8jSaY -tlu3zM63Nwf9JtmYhST/WSMDmu2dnajkXjjO11INb9I/bbEFa0nOipFGc/T2L/Coc3cOZayhjWZS -aX5LaAzHHjcng6WMxwLkFM1JAbBzs/3GkDpv0mztO+7skb6iQ12LAEpmJURw3kAP+HwV96LOPNde -E4yBFxgX0b3xdxA61GU5wSesVywlVP+i2k+KYTlerj1KjL0= ------END CERTIFICATE----- - -emSign Root CA - G1 -=================== ------BEGIN CERTIFICATE----- -MIIDlDCCAnygAwIBAgIKMfXkYgxsWO3W2DANBgkqhkiG9w0BAQsFADBnMQswCQYDVQQGEwJJTjET -MBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBUZWNobm9sb2dpZXMgTGltaXRl -ZDEcMBoGA1UEAxMTZW1TaWduIFJvb3QgQ0EgLSBHMTAeFw0xODAyMTgxODMwMDBaFw00MzAyMTgx -ODMwMDBaMGcxCzAJBgNVBAYTAklOMRMwEQYDVQQLEwplbVNpZ24gUEtJMSUwIwYDVQQKExxlTXVk -aHJhIFRlY2hub2xvZ2llcyBMaW1pdGVkMRwwGgYDVQQDExNlbVNpZ24gUm9vdCBDQSAtIEcxMIIB -IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAk0u76WaK7p1b1TST0Bsew+eeuGQzf2N4aLTN -LnF115sgxk0pvLZoYIr3IZpWNVrzdr3YzZr/k1ZLpVkGoZM0Kd0WNHVO8oG0x5ZOrRkVUkr+PHB1 -cM2vK6sVmjM8qrOLqs1D/fXqcP/tzxE7lM5OMhbTI0Aqd7OvPAEsbO2ZLIvZTmmYsvePQbAyeGHW -DV/D+qJAkh1cF+ZwPjXnorfCYuKrpDhMtTk1b+oDafo6VGiFbdbyL0NVHpENDtjVaqSW0RM8LHhQ -6DqS0hdW5TUaQBw+jSztOd9C4INBdN+jzcKGYEho42kLVACL5HZpIQ15TjQIXhTCzLG3rdd8cIrH -hQIDAQABo0IwQDAdBgNVHQ4EFgQU++8Nhp6w492pufEhF38+/PB3KxowDgYDVR0PAQH/BAQDAgEG -MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAFn/8oz1h31xPaOfG1vR2vjTnGs2 -vZupYeveFix0PZ7mddrXuqe8QhfnPZHr5X3dPpzxz5KsbEjMwiI/aTvFthUvozXGaCocV685743Q -NcMYDHsAVhzNixl03r4PEuDQqqE/AjSxcM6dGNYIAwlG7mDgfrbESQRRfXBgvKqy/3lyeqYdPV8q -+Mri/Tm3R7nrft8EI6/6nAYH6ftjk4BAtcZsCjEozgyfz7MjNYBBjWzEN3uBL4ChQEKF6dk4jeih -U80Bv2noWgbyRQuQ+q7hv53yrlc8pa6yVvSLZUDp/TGBLPQ5Cdjua6e0ph0VpZj3AYHYhX3zUVxx -iN66zB+Afko= ------END CERTIFICATE----- - -emSign ECC Root CA - G3 -======================= ------BEGIN CERTIFICATE----- -MIICTjCCAdOgAwIBAgIKPPYHqWhwDtqLhDAKBggqhkjOPQQDAzBrMQswCQYDVQQGEwJJTjETMBEG -A1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBUZWNobm9sb2dpZXMgTGltaXRlZDEg -MB4GA1UEAxMXZW1TaWduIEVDQyBSb290IENBIC0gRzMwHhcNMTgwMjE4MTgzMDAwWhcNNDMwMjE4 -MTgzMDAwWjBrMQswCQYDVQQGEwJJTjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11 -ZGhyYSBUZWNobm9sb2dpZXMgTGltaXRlZDEgMB4GA1UEAxMXZW1TaWduIEVDQyBSb290IENBIC0g -RzMwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQjpQy4LRL1KPOxst3iAhKAnjlfSU2fySU0WXTsuwYc -58Byr+iuL+FBVIcUqEqy6HyC5ltqtdyzdc6LBtCGI79G1Y4PPwT01xySfvalY8L1X44uT6EYGQIr -MgqCZH0Wk9GjQjBAMB0GA1UdDgQWBBR8XQKEE9TMipuBzhccLikenEhjQjAOBgNVHQ8BAf8EBAMC -AQYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNpADBmAjEAvvNhzwIQHWSVB7gYboiFBS+D -CBeQyh+KTOgNG3qxrdWBCUfvO6wIBHxcmbHtRwfSAjEAnbpV/KlK6O3t5nYBQnvI+GDZjVGLVTv7 -jHvrZQnD+JbNR6iC8hZVdyR+EhCVBCyj ------END CERTIFICATE----- - -emSign Root CA - C1 -=================== ------BEGIN CERTIFICATE----- -MIIDczCCAlugAwIBAgILAK7PALrEzzL4Q7IwDQYJKoZIhvcNAQELBQAwVjELMAkGA1UEBhMCVVMx -EzARBgNVBAsTCmVtU2lnbiBQS0kxFDASBgNVBAoTC2VNdWRocmEgSW5jMRwwGgYDVQQDExNlbVNp -Z24gUm9vdCBDQSAtIEMxMB4XDTE4MDIxODE4MzAwMFoXDTQzMDIxODE4MzAwMFowVjELMAkGA1UE -BhMCVVMxEzARBgNVBAsTCmVtU2lnbiBQS0kxFDASBgNVBAoTC2VNdWRocmEgSW5jMRwwGgYDVQQD -ExNlbVNpZ24gUm9vdCBDQSAtIEMxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAz+up -ufGZBczYKCFK83M0UYRWEPWgTywS4/oTmifQz/l5GnRfHXk5/Fv4cI7gklL35CX5VIPZHdPIWoU/ -Xse2B+4+wM6ar6xWQio5JXDWv7V7Nq2s9nPczdcdioOl+yuQFTdrHCZH3DspVpNqs8FqOp099cGX -OFgFixwR4+S0uF2FHYP+eF8LRWgYSKVGczQ7/g/IdrvHGPMF0Ybzhe3nudkyrVWIzqa2kbBPrH4V -I5b2P/AgNBbeCsbEBEV5f6f9vtKppa+cxSMq9zwhbL2vj07FOrLzNBL834AaSaTUqZX3noleooms -lMuoaJuvimUnzYnu3Yy1aylwQ6BpC+S5DwIDAQABo0IwQDAdBgNVHQ4EFgQU/qHgcB4qAzlSWkK+ -XJGFehiqTbUwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQAD -ggEBAMJKVvoVIXsoounlHfv4LcQ5lkFMOycsxGwYFYDGrK9HWS8mC+M2sO87/kOXSTKZEhVb3xEp -/6tT+LvBeA+snFOvV71ojD1pM/CjoCNjO2RnIkSt1XHLVip4kqNPEjE2NuLe/gDEo2APJ62gsIq1 -NnpSob0n9CAnYuhNlCQT5AoE6TyrLshDCUrGYQTlSTR+08TI9Q/Aqum6VF7zYytPT1DU/rl7mYw9 -wC68AivTxEDkigcxHpvOJpkT+xHqmiIMERnHXhuBUDDIlhJu58tBf5E7oke3VIAb3ADMmpDqw8NQ -BmIMMMAVSKeoWXzhriKi4gp6D/piq1JM4fHfyr6DDUI= ------END CERTIFICATE----- - -emSign ECC Root CA - C3 -======================= ------BEGIN CERTIFICATE----- -MIICKzCCAbGgAwIBAgIKe3G2gla4EnycqDAKBggqhkjOPQQDAzBaMQswCQYDVQQGEwJVUzETMBEG -A1UECxMKZW1TaWduIFBLSTEUMBIGA1UEChMLZU11ZGhyYSBJbmMxIDAeBgNVBAMTF2VtU2lnbiBF -Q0MgUm9vdCBDQSAtIEMzMB4XDTE4MDIxODE4MzAwMFoXDTQzMDIxODE4MzAwMFowWjELMAkGA1UE -BhMCVVMxEzARBgNVBAsTCmVtU2lnbiBQS0kxFDASBgNVBAoTC2VNdWRocmEgSW5jMSAwHgYDVQQD -ExdlbVNpZ24gRUNDIFJvb3QgQ0EgLSBDMzB2MBAGByqGSM49AgEGBSuBBAAiA2IABP2lYa57JhAd -6bciMK4G9IGzsUJxlTm801Ljr6/58pc1kjZGDoeVjbk5Wum739D+yAdBPLtVb4OjavtisIGJAnB9 -SMVK4+kiVCJNk7tCDK93nCOmfddhEc5lx/h//vXyqaNCMEAwHQYDVR0OBBYEFPtaSNCAIEDyqOkA -B2kZd6fmw/TPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MAoGCCqGSM49BAMDA2gA -MGUCMQC02C8Cif22TGK6Q04ThHK1rt0c3ta13FaPWEBaLd4gTCKDypOofu4SQMfWh0/434UCMBwU -ZOR8loMRnLDRWmFLpg9J0wD8ofzkpf9/rdcw0Md3f76BB1UwUCAU9Vc4CqgxUQ== ------END CERTIFICATE----- - -Hongkong Post Root CA 3 -======================= ------BEGIN CERTIFICATE----- -MIIFzzCCA7egAwIBAgIUCBZfikyl7ADJk0DfxMauI7gcWqQwDQYJKoZIhvcNAQELBQAwbzELMAkG -A1UEBhMCSEsxEjAQBgNVBAgTCUhvbmcgS29uZzESMBAGA1UEBxMJSG9uZyBLb25nMRYwFAYDVQQK -Ew1Ib25na29uZyBQb3N0MSAwHgYDVQQDExdIb25na29uZyBQb3N0IFJvb3QgQ0EgMzAeFw0xNzA2 -MDMwMjI5NDZaFw00MjA2MDMwMjI5NDZaMG8xCzAJBgNVBAYTAkhLMRIwEAYDVQQIEwlIb25nIEtv -bmcxEjAQBgNVBAcTCUhvbmcgS29uZzEWMBQGA1UEChMNSG9uZ2tvbmcgUG9zdDEgMB4GA1UEAxMX -SG9uZ2tvbmcgUG9zdCBSb290IENBIDMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCz -iNfqzg8gTr7m1gNt7ln8wlffKWihgw4+aMdoWJwcYEuJQwy51BWy7sFOdem1p+/l6TWZ5Mwc50tf -jTMwIDNT2aa71T4Tjukfh0mtUC1Qyhi+AViiE3CWu4mIVoBc+L0sPOFMV4i707mV78vH9toxdCim -5lSJ9UExyuUmGs2C4HDaOym71QP1mbpV9WTRYA6ziUm4ii8F0oRFKHyPaFASePwLtVPLwpgchKOe -sL4jpNrcyCse2m5FHomY2vkALgbpDDtw1VAliJnLzXNg99X/NWfFobxeq81KuEXryGgeDQ0URhLj -0mRiikKYvLTGCAj4/ahMZJx2Ab0vqWwzD9g/KLg8aQFChn5pwckGyuV6RmXpwtZQQS4/t+TtbNe/ -JgERohYpSms0BpDsE9K2+2p20jzt8NYt3eEV7KObLyzJPivkaTv/ciWxNoZbx39ri1UbSsUgYT2u -y1DhCDq+sI9jQVMwCFk8mB13umOResoQUGC/8Ne8lYePl8X+l2oBlKN8W4UdKjk60FSh0Tlxnf0h -+bV78OLgAo9uliQlLKAeLKjEiafv7ZkGL7YKTE/bosw3Gq9HhS2KX8Q0NEwA/RiTZxPRN+ZItIsG -xVd7GYYKecsAyVKvQv83j+GjHno9UKtjBucVtT+2RTeUN7F+8kjDf8V1/peNRY8apxpyKBpADwID -AQABo2MwYTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAfBgNVHSMEGDAWgBQXnc0e -i9Y5K3DTXNSguB+wAPzFYTAdBgNVHQ4EFgQUF53NHovWOStw01zUoLgfsAD8xWEwDQYJKoZIhvcN -AQELBQADggIBAFbVe27mIgHSQpsY1Q7XZiNc4/6gx5LS6ZStS6LG7BJ8dNVI0lkUmcDrudHr9Egw -W62nV3OZqdPlt9EuWSRY3GguLmLYauRwCy0gUCCkMpXRAJi70/33MvJJrsZ64Ee+bs7Lo3I6LWld -y8joRTnU+kLBEUx3XZL7av9YROXrgZ6voJmtvqkBZss4HTzfQx/0TW60uhdG/H39h4F5ag0zD/ov -+BS5gLNdTaqX4fnkGMX41TiMJjz98iji7lpJiCzfeT2OnpA8vUFKOt1b9pq0zj8lMH8yfaIDlNDc -eqFS3m6TjRgm/VWsvY+b0s+v54Ysyx8Jb6NvqYTUc79NoXQbTiNg8swOqn+knEwlqLJmOzj/2ZQw -9nKEvmhVEA/GcywWaZMH/rFF7buiVWqw2rVKAiUnhde3t4ZEFolsgCs+l6mc1X5VTMbeRRAc6uk7 -nwNT7u56AQIWeNTowr5GdogTPyK7SBIdUgC0An4hGh6cJfTzPV4e0hz5sy229zdcxsshTrD3mUcY -hcErulWuBurQB7Lcq9CClnXO0lD+mefPL5/ndtFhKvshuzHQqp9HpLIiyhY6UFfEW0NnxWViA0kB -60PZ2Pierc+xYw5F9KBaLJstxabArahH9CdMOA0uG0k7UvToiIMrVCjU8jVStDKDYmlkDJGcn5fq -dBb9HxEGmpv0 ------END CERTIFICATE----- - -Entrust Root Certification Authority - G4 -========================================= ------BEGIN CERTIFICATE----- -MIIGSzCCBDOgAwIBAgIRANm1Q3+vqTkPAAAAAFVlrVgwDQYJKoZIhvcNAQELBQAwgb4xCzAJBgNV -BAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1c3Qu -bmV0L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxNSBFbnRydXN0LCBJbmMuIC0gZm9yIGF1 -dGhvcml6ZWQgdXNlIG9ubHkxMjAwBgNVBAMTKUVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1 -dGhvcml0eSAtIEc0MB4XDTE1MDUyNzExMTExNloXDTM3MTIyNzExNDExNlowgb4xCzAJBgNVBAYT -AlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1c3QubmV0 -L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxNSBFbnRydXN0LCBJbmMuIC0gZm9yIGF1dGhv -cml6ZWQgdXNlIG9ubHkxMjAwBgNVBAMTKUVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhv -cml0eSAtIEc0MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAsewsQu7i0TD/pZJH4i3D -umSXbcr3DbVZwbPLqGgZ2K+EbTBwXX7zLtJTmeH+H17ZSK9dE43b/2MzTdMAArzE+NEGCJR5WIoV -3imz/f3ET+iq4qA7ec2/a0My3dl0ELn39GjUu9CH1apLiipvKgS1sqbHoHrmSKvS0VnM1n4j5pds -8ELl3FFLFUHtSUrJ3hCX1nbB76W1NhSXNdh4IjVS70O92yfbYVaCNNzLiGAMC1rlLAHGVK/XqsEQ -e9IFWrhAnoanw5CGAlZSCXqc0ieCU0plUmr1POeo8pyvi73TDtTUXm6Hnmo9RR3RXRv06QqsYJn7 -ibT/mCzPfB3pAqoEmh643IhuJbNsZvc8kPNXwbMv9W3y+8qh+CmdRouzavbmZwe+LGcKKh9asj5X -xNMhIWNlUpEbsZmOeX7m640A2Vqq6nPopIICR5b+W45UYaPrL0swsIsjdXJ8ITzI9vF01Bx7owVV -7rtNOzK+mndmnqxpkCIHH2E6lr7lmk/MBTwoWdPBDFSoWWG9yHJM6Nyfh3+9nEg2XpWjDrk4JFX8 -dWbrAuMINClKxuMrLzOg2qOGpRKX/YAr2hRC45K9PvJdXmd0LhyIRyk0X+IyqJwlN4y6mACXi0mW -Hv0liqzc2thddG5msP9E36EYxr5ILzeUePiVSj9/E15dWf10hkNjc0kCAwEAAaNCMEAwDwYDVR0T -AQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJ84xFYjwznooHFs6FRM5Og6sb9n -MA0GCSqGSIb3DQEBCwUAA4ICAQAS5UKme4sPDORGpbZgQIeMJX6tuGguW8ZAdjwD+MlZ9POrYs4Q -jbRaZIxowLByQzTSGwv2LFPSypBLhmb8qoMi9IsabyZIrHZ3CL/FmFz0Jomee8O5ZDIBf9PD3Vht -7LGrhFV0d4QEJ1JrhkzO3bll/9bGXp+aEJlLdWr+aumXIOTkdnrG0CSqkM0gkLpHZPt/B7NTeLUK -YvJzQ85BK4FqLoUWlFPUa19yIqtRLULVAJyZv967lDtX/Zr1hstWO1uIAeV8KEsD+UmDfLJ/fOPt -jqF/YFOOVZ1QNBIPt5d7bIdKROf1beyAN/BYGW5KaHbwH5Lk6rWS02FREAutp9lfx1/cH6NcjKF+ -m7ee01ZvZl4HliDtC3T7Zk6LERXpgUl+b7DUUH8i119lAg2m9IUe2K4GS0qn0jFmwvjO5QimpAKW -RGhXxNUzzxkvFMSUHHuk2fCfDrGA4tGeEWSpiBE6doLlYsKA2KSD7ZPvfC+QsDJMlhVoSFLUmQjA -JOgc47OlIQ6SwJAfzyBfyjs4x7dtOvPmRLgOMWuIjnDrnBdSqEGULoe256YSxXXfW8AKbnuk5F6G -+TaU33fD6Q3AOfF5u0aOq0NZJ7cguyPpVkAh7DE9ZapD8j3fcEThuk0mEDuYn/PIjhs4ViFqUZPT -kcpG2om3PVODLAgfi49T3f+sHw== ------END CERTIFICATE----- - -Microsoft ECC Root Certificate Authority 2017 -============================================= ------BEGIN CERTIFICATE----- -MIICWTCCAd+gAwIBAgIQZvI9r4fei7FK6gxXMQHC7DAKBggqhkjOPQQDAzBlMQswCQYDVQQGEwJV -UzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYDVQQDEy1NaWNyb3NvZnQgRUND -IFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTcwHhcNMTkxMjE4MjMwNjQ1WhcNNDIwNzE4 -MjMxNjA0WjBlMQswCQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYw -NAYDVQQDEy1NaWNyb3NvZnQgRUNDIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTcwdjAQ -BgcqhkjOPQIBBgUrgQQAIgNiAATUvD0CQnVBEyPNgASGAlEvaqiBYgtlzPbKnR5vSmZRogPZnZH6 -thaxjG7efM3beaYvzrvOcS/lpaso7GMEZpn4+vKTEAXhgShC48Zo9OYbhGBKia/teQ87zvH2RPUB -eMCjVDBSMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTIy5lycFIM -+Oa+sgRXKSrPQhDtNTAQBgkrBgEEAYI3FQEEAwIBADAKBggqhkjOPQQDAwNoADBlAjBY8k3qDPlf -Xu5gKcs68tvWMoQZP3zVL8KxzJOuULsJMsbG7X7JNpQS5GiFBqIb0C8CMQCZ6Ra0DvpWSNSkMBaR -eNtUjGUBiudQZsIxtzm6uBoiB078a1QWIP8rtedMDE2mT3M= ------END CERTIFICATE----- - -Microsoft RSA Root Certificate Authority 2017 -============================================= ------BEGIN CERTIFICATE----- -MIIFqDCCA5CgAwIBAgIQHtOXCV/YtLNHcB6qvn9FszANBgkqhkiG9w0BAQwFADBlMQswCQYDVQQG -EwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYDVQQDEy1NaWNyb3NvZnQg -UlNBIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTcwHhcNMTkxMjE4MjI1MTIyWhcNNDIw -NzE4MjMwMDIzWjBlMQswCQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9u -MTYwNAYDVQQDEy1NaWNyb3NvZnQgUlNBIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTcw -ggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKW76UM4wplZEWCpW9R2LBifOZNt9GkMml -7Xhqb0eRaPgnZ1AzHaGm++DlQ6OEAlcBXZxIQIJTELy/xztokLaCLeX0ZdDMbRnMlfl7rEqUrQ7e -S0MdhweSE5CAg2Q1OQT85elss7YfUJQ4ZVBcF0a5toW1HLUX6NZFndiyJrDKxHBKrmCk3bPZ7Pw7 -1VdyvD/IybLeS2v4I2wDwAW9lcfNcztmgGTjGqwu+UcF8ga2m3P1eDNbx6H7JyqhtJqRjJHTOoI+ -dkC0zVJhUXAoP8XFWvLJjEm7FFtNyP9nTUwSlq31/niol4fX/V4ggNyhSyL71Imtus5Hl0dVe49F -yGcohJUcaDDv70ngNXtk55iwlNpNhTs+VcQor1fznhPbRiefHqJeRIOkpcrVE7NLP8TjwuaGYaRS -MLl6IE9vDzhTyzMMEyuP1pq9KsgtsRx9S1HKR9FIJ3Jdh+vVReZIZZ2vUpC6W6IYZVcSn2i51BVr -lMRpIpj0M+Dt+VGOQVDJNE92kKz8OMHY4Xu54+OU4UZpyw4KUGsTuqwPN1q3ErWQgR5WrlcihtnJ -0tHXUeOrO8ZV/R4O03QK0dqq6mm4lyiPSMQH+FJDOvTKVTUssKZqwJz58oHhEmrARdlns87/I6KJ -ClTUFLkqqNfs+avNJVgyeY+QW5g5xAgGwax/Dj0ApQIDAQABo1QwUjAOBgNVHQ8BAf8EBAMCAYYw -DwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUCctZf4aycI8awznjwNnpv7tNsiMwEAYJKwYBBAGC -NxUBBAMCAQAwDQYJKoZIhvcNAQEMBQADggIBAKyvPl3CEZaJjqPnktaXFbgToqZCLgLNFgVZJ8og -6Lq46BrsTaiXVq5lQ7GPAJtSzVXNUzltYkyLDVt8LkS/gxCP81OCgMNPOsduET/m4xaRhPtthH80 -dK2Jp86519efhGSSvpWhrQlTM93uCupKUY5vVau6tZRGrox/2KJQJWVggEbbMwSubLWYdFQl3JPk -+ONVFT24bcMKpBLBaYVu32TxU5nhSnUgnZUP5NbcA/FZGOhHibJXWpS2qdgXKxdJ5XbLwVaZOjex -/2kskZGT4d9Mozd2TaGf+G0eHdP67Pv0RR0Tbc/3WeUiJ3IrhvNXuzDtJE3cfVa7o7P4NHmJweDy -AmH3pvwPuxwXC65B2Xy9J6P9LjrRk5Sxcx0ki69bIImtt2dmefU6xqaWM/5TkshGsRGRxpl/j8nW -ZjEgQRCHLQzWwa80mMpkg/sTV9HB8Dx6jKXB/ZUhoHHBk2dxEuqPiAppGWSZI1b7rCoucL5mxAyE -7+WL85MB+GqQk2dLsmijtWKP6T+MejteD+eMuMZ87zf9dOLITzNy4ZQ5bb0Sr74MTnB8G2+NszKT -c0QWbej09+CVgI+WXTik9KveCjCHk9hNAHFiRSdLOkKEW39lt2c0Ui2cFmuqqNh7o0JMcccMyj6D -5KbvtwEwXlGjefVwaaZBRA+GsCyRxj3qrg+E ------END CERTIFICATE----- - -e-Szigno Root CA 2017 -===================== ------BEGIN CERTIFICATE----- -MIICQDCCAeWgAwIBAgIMAVRI7yH9l1kN9QQKMAoGCCqGSM49BAMCMHExCzAJBgNVBAYTAkhVMREw -DwYDVQQHDAhCdWRhcGVzdDEWMBQGA1UECgwNTWljcm9zZWMgTHRkLjEXMBUGA1UEYQwOVkFUSFUt -MjM1ODQ0OTcxHjAcBgNVBAMMFWUtU3ppZ25vIFJvb3QgQ0EgMjAxNzAeFw0xNzA4MjIxMjA3MDZa -Fw00MjA4MjIxMjA3MDZaMHExCzAJBgNVBAYTAkhVMREwDwYDVQQHDAhCdWRhcGVzdDEWMBQGA1UE -CgwNTWljcm9zZWMgTHRkLjEXMBUGA1UEYQwOVkFUSFUtMjM1ODQ0OTcxHjAcBgNVBAMMFWUtU3pp -Z25vIFJvb3QgQ0EgMjAxNzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABJbcPYrYsHtvxie+RJCx -s1YVe45DJH0ahFnuY2iyxl6H0BVIHqiQrb1TotreOpCmYF9oMrWGQd+HWyx7xf58etqjYzBhMA8G -A1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBSHERUI0arBeAyxr87GyZDv -vzAEwDAfBgNVHSMEGDAWgBSHERUI0arBeAyxr87GyZDvvzAEwDAKBggqhkjOPQQDAgNJADBGAiEA -tVfd14pVCzbhhkT61NlojbjcI4qKDdQvfepz7L9NbKgCIQDLpbQS+ue16M9+k/zzNY9vTlp8tLxO -svxyqltZ+efcMQ== ------END CERTIFICATE----- - -certSIGN Root CA G2 -=================== ------BEGIN CERTIFICATE----- -MIIFRzCCAy+gAwIBAgIJEQA0tk7GNi02MA0GCSqGSIb3DQEBCwUAMEExCzAJBgNVBAYTAlJPMRQw -EgYDVQQKEwtDRVJUU0lHTiBTQTEcMBoGA1UECxMTY2VydFNJR04gUk9PVCBDQSBHMjAeFw0xNzAy -MDYwOTI3MzVaFw00MjAyMDYwOTI3MzVaMEExCzAJBgNVBAYTAlJPMRQwEgYDVQQKEwtDRVJUU0lH -TiBTQTEcMBoGA1UECxMTY2VydFNJR04gUk9PVCBDQSBHMjCCAiIwDQYJKoZIhvcNAQEBBQADggIP -ADCCAgoCggIBAMDFdRmRfUR0dIf+DjuW3NgBFszuY5HnC2/OOwppGnzC46+CjobXXo9X69MhWf05 -N0IwvlDqtg+piNguLWkh59E3GE59kdUWX2tbAMI5Qw02hVK5U2UPHULlj88F0+7cDBrZuIt4Imfk -abBoxTzkbFpG583H+u/E7Eu9aqSs/cwoUe+StCmrqzWaTOTECMYmzPhpn+Sc8CnTXPnGFiWeI8Mg -wT0PPzhAsP6CRDiqWhqKa2NYOLQV07YRaXseVO6MGiKscpc/I1mbySKEwQdPzH/iV8oScLumZfNp -dWO9lfsbl83kqK/20U6o2YpxJM02PbyWxPFsqa7lzw1uKA2wDrXKUXt4FMMgL3/7FFXhEZn91Qqh -ngLjYl/rNUssuHLoPj1PrCy7Lobio3aP5ZMqz6WryFyNSwb/EkaseMsUBzXgqd+L6a8VTxaJW732 -jcZZroiFDsGJ6x9nxUWO/203Nit4ZoORUSs9/1F3dmKh7Gc+PoGD4FapUB8fepmrY7+EF3fxDTvf -95xhszWYijqy7DwaNz9+j5LP2RIUZNoQAhVB/0/E6xyjyfqZ90bp4RjZsbgyLcsUDFDYg2WD7rlc -z8sFWkz6GZdr1l0T08JcVLwyc6B49fFtHsufpaafItzRUZ6CeWRgKRM+o/1Pcmqr4tTluCRVLERL -iohEnMqE0yo7AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1Ud -DgQWBBSCIS1mxteg4BXrzkwJd8RgnlRuAzANBgkqhkiG9w0BAQsFAAOCAgEAYN4auOfyYILVAzOB -ywaK8SJJ6ejqkX/GM15oGQOGO0MBzwdw5AgeZYWR5hEit/UCI46uuR59H35s5r0l1ZUa8gWmr4UC -b6741jH/JclKyMeKqdmfS0mbEVeZkkMR3rYzpMzXjWR91M08KCy0mpbqTfXERMQlqiCA2ClV9+BB -/AYm/7k29UMUA2Z44RGx2iBfRgB4ACGlHgAoYXhvqAEBj500mv/0OJD7uNGzcgbJceaBxXntC6Z5 -8hMLnPddDnskk7RI24Zf3lCGeOdA5jGokHZwYa+cNywRtYK3qq4kNFtyDGkNzVmf9nGvnAvRCjj5 -BiKDUyUM/FHE5r7iOZULJK2v0ZXkltd0ZGtxTgI8qoXzIKNDOXZbbFD+mpwUHmUUihW9o4JFWklW -atKcsWMy5WHgUyIOpwpJ6st+H6jiYoD2EEVSmAYY3qXNL3+q1Ok+CHLsIwMCPKaq2LxndD0UF/tU -Sxfj03k9bWtJySgOLnRQvwzZRjoQhsmnP+mg7H/rpXdYaXHmgwo38oZJar55CJD2AhZkPuXaTH4M -NMn5X7azKFGnpyuqSfqNZSlO42sTp5SjLVFteAxEy9/eCG/Oo2Sr05WE1LlSVHJ7liXMvGnjSG4N -0MedJ5qq+BOS3R7fY581qRY27Iy4g/Q9iY/NtBde17MXQRBdJ3NghVdJIgc= ------END CERTIFICATE----- - -Trustwave Global Certification Authority -======================================== ------BEGIN CERTIFICATE----- -MIIF2jCCA8KgAwIBAgIMBfcOhtpJ80Y1LrqyMA0GCSqGSIb3DQEBCwUAMIGIMQswCQYDVQQGEwJV -UzERMA8GA1UECAwISWxsaW5vaXMxEDAOBgNVBAcMB0NoaWNhZ28xITAfBgNVBAoMGFRydXN0d2F2 -ZSBIb2xkaW5ncywgSW5jLjExMC8GA1UEAwwoVHJ1c3R3YXZlIEdsb2JhbCBDZXJ0aWZpY2F0aW9u -IEF1dGhvcml0eTAeFw0xNzA4MjMxOTM0MTJaFw00MjA4MjMxOTM0MTJaMIGIMQswCQYDVQQGEwJV -UzERMA8GA1UECAwISWxsaW5vaXMxEDAOBgNVBAcMB0NoaWNhZ28xITAfBgNVBAoMGFRydXN0d2F2 -ZSBIb2xkaW5ncywgSW5jLjExMC8GA1UEAwwoVHJ1c3R3YXZlIEdsb2JhbCBDZXJ0aWZpY2F0aW9u -IEF1dGhvcml0eTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALldUShLPDeS0YLOvR29 -zd24q88KPuFd5dyqCblXAj7mY2Hf8g+CY66j96xz0XznswuvCAAJWX/NKSqIk4cXGIDtiLK0thAf -LdZfVaITXdHG6wZWiYj+rDKd/VzDBcdu7oaJuogDnXIhhpCujwOl3J+IKMujkkkP7NAP4m1ET4Bq -stTnoApTAbqOl5F2brz81Ws25kCI1nsvXwXoLG0R8+eyvpJETNKXpP7ScoFDB5zpET71ixpZfR9o -WN0EACyW80OzfpgZdNmcc9kYvkHHNHnZ9GLCQ7mzJ7Aiy/k9UscwR7PJPrhq4ufogXBeQotPJqX+ -OsIgbrv4Fo7NDKm0G2x2EOFYeUY+VM6AqFcJNykbmROPDMjWLBz7BegIlT1lRtzuzWniTY+HKE40 -Cz7PFNm73bZQmq131BnW2hqIyE4bJ3XYsgjxroMwuREOzYfwhI0Vcnyh78zyiGG69Gm7DIwLdVcE -uE4qFC49DxweMqZiNu5m4iK4BUBjECLzMx10coos9TkpoNPnG4CELcU9402x/RpvumUHO1jsQkUm -+9jaJXLE9gCxInm943xZYkqcBW89zubWR2OZxiRvchLIrH+QtAuRcOi35hYQcRfO3gZPSEF9NUqj -ifLJS3tBEW1ntwiYTOURGa5CgNz7kAXU+FDKvuStx8KU1xad5hePrzb7AgMBAAGjQjBAMA8GA1Ud -EwEB/wQFMAMBAf8wHQYDVR0OBBYEFJngGWcNYtt2s9o9uFvo/ULSMQ6HMA4GA1UdDwEB/wQEAwIB -BjANBgkqhkiG9w0BAQsFAAOCAgEAmHNw4rDT7TnsTGDZqRKGFx6W0OhUKDtkLSGm+J1WE2pIPU/H -PinbbViDVD2HfSMF1OQc3Og4ZYbFdada2zUFvXfeuyk3QAUHw5RSn8pk3fEbK9xGChACMf1KaA0H -ZJDmHvUqoai7PF35owgLEQzxPy0QlG/+4jSHg9bP5Rs1bdID4bANqKCqRieCNqcVtgimQlRXtpla -4gt5kNdXElE1GYhBaCXUNxeEFfsBctyV3lImIJgm4nb1J2/6ADtKYdkNy1GTKv0WBpanI5ojSP5R -vbbEsLFUzt5sQa0WZ37b/TjNuThOssFgy50X31ieemKyJo90lZvkWx3SD92YHJtZuSPTMaCm/zjd -zyBP6VhWOmfD0faZmZ26NraAL4hHT4a/RDqA5Dccprrql5gR0IRiR2Qequ5AvzSxnI9O4fKSTx+O -856X3vOmeWqJcU9LJxdI/uz0UA9PSX3MReO9ekDFQdxhVicGaeVyQYHTtgGJoC86cnn+OjC/QezH -Yj6RS8fZMXZC+fc8Y+wmjHMMfRod6qh8h6jCJ3zhM0EPz8/8AKAigJ5Kp28AsEFFtyLKaEjFQqKu -3R3y4G5OBVixwJAWKqQ9EEC+j2Jjg6mcgn0tAumDMHzLJ8n9HmYAsC7TIS+OMxZsmO0QqAfWzJPP -29FpHOTKyeC2nOnOcXHebD8WpHk= ------END CERTIFICATE----- - -Trustwave Global ECC P256 Certification Authority -================================================= ------BEGIN CERTIFICATE----- -MIICYDCCAgegAwIBAgIMDWpfCD8oXD5Rld9dMAoGCCqGSM49BAMCMIGRMQswCQYDVQQGEwJVUzER -MA8GA1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAfBgNVBAoTGFRydXN0d2F2ZSBI -b2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3YXZlIEdsb2JhbCBFQ0MgUDI1NiBDZXJ0aWZp -Y2F0aW9uIEF1dGhvcml0eTAeFw0xNzA4MjMxOTM1MTBaFw00MjA4MjMxOTM1MTBaMIGRMQswCQYD -VQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAfBgNVBAoTGFRy -dXN0d2F2ZSBIb2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3YXZlIEdsb2JhbCBFQ0MgUDI1 -NiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABH77bOYj -43MyCMpg5lOcunSNGLB4kFKA3TjASh3RqMyTpJcGOMoNFWLGjgEqZZ2q3zSRLoHB5DOSMcT9CTqm -P62jQzBBMA8GA1UdEwEB/wQFMAMBAf8wDwYDVR0PAQH/BAUDAwcGADAdBgNVHQ4EFgQUo0EGrJBt -0UrrdaVKEJmzsaGLSvcwCgYIKoZIzj0EAwIDRwAwRAIgB+ZU2g6gWrKuEZ+Hxbb/ad4lvvigtwjz -RM4q3wghDDcCIC0mA6AFvWvR9lz4ZcyGbbOcNEhjhAnFjXca4syc4XR7 ------END CERTIFICATE----- - -Trustwave Global ECC P384 Certification Authority -================================================= ------BEGIN CERTIFICATE----- -MIICnTCCAiSgAwIBAgIMCL2Fl2yZJ6SAaEc7MAoGCCqGSM49BAMDMIGRMQswCQYDVQQGEwJVUzER -MA8GA1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAfBgNVBAoTGFRydXN0d2F2ZSBI -b2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3YXZlIEdsb2JhbCBFQ0MgUDM4NCBDZXJ0aWZp -Y2F0aW9uIEF1dGhvcml0eTAeFw0xNzA4MjMxOTM2NDNaFw00MjA4MjMxOTM2NDNaMIGRMQswCQYD -VQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAfBgNVBAoTGFRy -dXN0d2F2ZSBIb2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3YXZlIEdsb2JhbCBFQ0MgUDM4 -NCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTB2MBAGByqGSM49AgEGBSuBBAAiA2IABGvaDXU1CDFH -Ba5FmVXxERMuSvgQMSOjfoPTfygIOiYaOs+Xgh+AtycJj9GOMMQKmw6sWASr9zZ9lCOkmwqKi6vr -/TklZvFe/oyujUF5nQlgziip04pt89ZF1PKYhDhloKNDMEEwDwYDVR0TAQH/BAUwAwEB/zAPBgNV -HQ8BAf8EBQMDBwYAMB0GA1UdDgQWBBRVqYSJ0sEyvRjLbKYHTsjnnb6CkDAKBggqhkjOPQQDAwNn -ADBkAjA3AZKXRRJ+oPM+rRk6ct30UJMDEr5E0k9BpIycnR+j9sKS50gU/k6bpZFXrsY3crsCMGcl -CrEMXu6pY5Jv5ZAL/mYiykf9ijH3g/56vxC+GCsej/YpHpRZ744hN8tRmKVuSw== ------END CERTIFICATE----- - -NAVER Global Root Certification Authority -========================================= ------BEGIN CERTIFICATE----- -MIIFojCCA4qgAwIBAgIUAZQwHqIL3fXFMyqxQ0Rx+NZQTQ0wDQYJKoZIhvcNAQEMBQAwaTELMAkG -A1UEBhMCS1IxJjAkBgNVBAoMHU5BVkVSIEJVU0lORVNTIFBMQVRGT1JNIENvcnAuMTIwMAYDVQQD -DClOQVZFUiBHbG9iYWwgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0xNzA4MTgwODU4 -NDJaFw0zNzA4MTgyMzU5NTlaMGkxCzAJBgNVBAYTAktSMSYwJAYDVQQKDB1OQVZFUiBCVVNJTkVT -UyBQTEFURk9STSBDb3JwLjEyMDAGA1UEAwwpTkFWRVIgR2xvYmFsIFJvb3QgQ2VydGlmaWNhdGlv -biBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC21PGTXLVAiQqrDZBb -UGOukJR0F0Vy1ntlWilLp1agS7gvQnXp2XskWjFlqxcX0TM62RHcQDaH38dq6SZeWYp34+hInDEW -+j6RscrJo+KfziFTowI2MMtSAuXaMl3Dxeb57hHHi8lEHoSTGEq0n+USZGnQJoViAbbJAh2+g1G7 -XNr4rRVqmfeSVPc0W+m/6imBEtRTkZazkVrd/pBzKPswRrXKCAfHcXLJZtM0l/aM9BhK4dA9WkW2 -aacp+yPOiNgSnABIqKYPszuSjXEOdMWLyEz59JuOuDxp7W87UC9Y7cSw0BwbagzivESq2M0UXZR4 -Yb8ObtoqvC8MC3GmsxY/nOb5zJ9TNeIDoKAYv7vxvvTWjIcNQvcGufFt7QSUqP620wbGQGHfnZ3z -VHbOUzoBppJB7ASjjw2i1QnK1sua8e9DXcCrpUHPXFNwcMmIpi3Ua2FzUCaGYQ5fG8Ir4ozVu53B -A0K6lNpfqbDKzE0K70dpAy8i+/Eozr9dUGWokG2zdLAIx6yo0es+nPxdGoMuK8u180SdOqcXYZai -cdNwlhVNt0xz7hlcxVs+Qf6sdWA7G2POAN3aCJBitOUt7kinaxeZVL6HSuOpXgRM6xBtVNbv8ejy -YhbLgGvtPe31HzClrkvJE+2KAQHJuFFYwGY6sWZLxNUxAmLpdIQM201GLQIDAQABo0IwQDAdBgNV -HQ4EFgQU0p+I36HNLL3s9TsBAZMzJ7LrYEswDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMB -Af8wDQYJKoZIhvcNAQEMBQADggIBADLKgLOdPVQG3dLSLvCkASELZ0jKbY7gyKoNqo0hV4/GPnrK -21HUUrPUloSlWGB/5QuOH/XcChWB5Tu2tyIvCZwTFrFsDDUIbatjcu3cvuzHV+YwIHHW1xDBE1UB -jCpD5EHxzzp6U5LOogMFDTjfArsQLtk70pt6wKGm+LUx5vR1yblTmXVHIloUFcd4G7ad6Qz4G3bx -hYTeodoS76TiEJd6eN4MUZeoIUCLhr0N8F5OSza7OyAfikJW4Qsav3vQIkMsRIz75Sq0bBwcupTg -E34h5prCy8VCZLQelHsIJchxzIdFV4XTnyliIoNRlwAYl3dqmJLJfGBs32x9SuRwTMKeuB330DTH -D8z7p/8Dvq1wkNoL3chtl1+afwkyQf3NosxabUzyqkn+Zvjp2DXrDige7kgvOtB5CTh8piKCk5XQ -A76+AqAF3SAi428diDRgxuYKuQl1C/AH6GmWNcf7I4GOODm4RStDeKLRLBT/DShycpWbXgnbiUSY -qqFJu3FS8r/2/yehNq+4tneI3TqkbZs0kNwUXTC/t+sX5Ie3cdCh13cV1ELX8vMxmV2b3RZtP+oG -I/hGoiLtk/bdmuYqh7GYVPEi92tF4+KOdh2ajcQGjTa3FPOdVGm3jjzVpG2Tgbet9r1ke8LJaDmg -kpzNNIaRkPpkUZ3+/uul9XXeifdy ------END CERTIFICATE----- - -AC RAIZ FNMT-RCM SERVIDORES SEGUROS -=================================== ------BEGIN CERTIFICATE----- -MIICbjCCAfOgAwIBAgIQYvYybOXE42hcG2LdnC6dlTAKBggqhkjOPQQDAzB4MQswCQYDVQQGEwJF -UzERMA8GA1UECgwIRk5NVC1SQ00xDjAMBgNVBAsMBUNlcmVzMRgwFgYDVQRhDA9WQVRFUy1RMjgy -NjAwNEoxLDAqBgNVBAMMI0FDIFJBSVogRk5NVC1SQ00gU0VSVklET1JFUyBTRUdVUk9TMB4XDTE4 -MTIyMDA5MzczM1oXDTQzMTIyMDA5MzczM1oweDELMAkGA1UEBhMCRVMxETAPBgNVBAoMCEZOTVQt -UkNNMQ4wDAYDVQQLDAVDZXJlczEYMBYGA1UEYQwPVkFURVMtUTI4MjYwMDRKMSwwKgYDVQQDDCNB -QyBSQUlaIEZOTVQtUkNNIFNFUlZJRE9SRVMgU0VHVVJPUzB2MBAGByqGSM49AgEGBSuBBAAiA2IA -BPa6V1PIyqvfNkpSIeSX0oNnnvBlUdBeh8dHsVnyV0ebAAKTRBdp20LHsbI6GA60XYyzZl2hNPk2 -LEnb80b8s0RpRBNm/dfF/a82Tc4DTQdxz69qBdKiQ1oKUm8BA06Oi6NCMEAwDwYDVR0TAQH/BAUw -AwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFAG5L++/EYZg8k/QQW6rcx/n0m5JMAoGCCqG -SM49BAMDA2kAMGYCMQCuSuMrQMN0EfKVrRYj3k4MGuZdpSRea0R7/DjiT8ucRRcRTBQnJlU5dUoD -zBOQn5ICMQD6SmxgiHPz7riYYqnOK8LZiqZwMR2vsJRM60/G49HzYqc8/5MuB1xJAWdpEgJyv+c= ------END CERTIFICATE----- - -GlobalSign Root R46 -=================== ------BEGIN CERTIFICATE----- -MIIFWjCCA0KgAwIBAgISEdK7udcjGJ5AXwqdLdDfJWfRMA0GCSqGSIb3DQEBDAUAMEYxCzAJBgNV -BAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRwwGgYDVQQDExNHbG9iYWxTaWduIFJv -b3QgUjQ2MB4XDTE5MDMyMDAwMDAwMFoXDTQ2MDMyMDAwMDAwMFowRjELMAkGA1UEBhMCQkUxGTAX -BgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExHDAaBgNVBAMTE0dsb2JhbFNpZ24gUm9vdCBSNDYwggIi -MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCsrHQy6LNl5brtQyYdpokNRbopiLKkHWPd08Es -CVeJOaFV6Wc0dwxu5FUdUiXSE2te4R2pt32JMl8Nnp8semNgQB+msLZ4j5lUlghYruQGvGIFAha/ -r6gjA7aUD7xubMLL1aa7DOn2wQL7Id5m3RerdELv8HQvJfTqa1VbkNud316HCkD7rRlr+/fKYIje -2sGP1q7Vf9Q8g+7XFkyDRTNrJ9CG0Bwta/OrffGFqfUo0q3v84RLHIf8E6M6cqJaESvWJ3En7YEt -bWaBkoe0G1h6zD8K+kZPTXhc+CtI4wSEy132tGqzZfxCnlEmIyDLPRT5ge1lFgBPGmSXZgjPjHvj -K8Cd+RTyG/FWaha/LIWFzXg4mutCagI0GIMXTpRW+LaCtfOW3T3zvn8gdz57GSNrLNRyc0NXfeD4 -12lPFzYE+cCQYDdF3uYM2HSNrpyibXRdQr4G9dlkbgIQrImwTDsHTUB+JMWKmIJ5jqSngiCNI/on -ccnfxkF0oE32kRbcRoxfKWMxWXEM2G/CtjJ9++ZdU6Z+Ffy7dXxd7Pj2Fxzsx2sZy/N78CsHpdls -eVR2bJ0cpm4O6XkMqCNqo98bMDGfsVR7/mrLZqrcZdCinkqaByFrgY/bxFn63iLABJzjqls2k+g9 -vXqhnQt2sQvHnf3PmKgGwvgqo6GDoLclcqUC4wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYD -VR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA1yrc4GHqMywptWU4jaWSf8FmSwwDQYJKoZIhvcNAQEM -BQADggIBAHx47PYCLLtbfpIrXTncvtgdokIzTfnvpCo7RGkerNlFo048p9gkUbJUHJNOxO97k4Vg -JuoJSOD1u8fpaNK7ajFxzHmuEajwmf3lH7wvqMxX63bEIaZHU1VNaL8FpO7XJqti2kM3S+LGteWy -gxk6x9PbTZ4IevPuzz5i+6zoYMzRx6Fcg0XERczzF2sUyQQCPtIkpnnpHs6i58FZFZ8d4kuaPp92 -CC1r2LpXFNqD6v6MVenQTqnMdzGxRBF6XLE+0xRFFRhiJBPSy03OXIPBNvIQtQ6IbbjhVp+J3pZm -OUdkLG5NrmJ7v2B0GbhWrJKsFjLtrWhV/pi60zTe9Mlhww6G9kuEYO4Ne7UyWHmRVSyBQ7N0H3qq -JZ4d16GLuc1CLgSkZoNNiTW2bKg2SnkheCLQQrzRQDGQob4Ez8pn7fXwgNNgyYMqIgXQBztSvwye -qiv5u+YfjyW6hY0XHgL+XVAEV8/+LbzvXMAaq7afJMbfc2hIkCwU9D9SGuTSyxTDYWnP4vkYxboz -nxSjBF25cfe1lNj2M8FawTSLfJvdkzrnE6JwYZ+vj+vYxXX4M2bUdGc6N3ec592kD3ZDZopD8p/7 -DEJ4Y9HiD2971KE9dJeFt0g5QdYg/NA6s/rob8SKunE3vouXsXgxT7PntgMTzlSdriVZzH81Xwj3 -QEUxeCp6 ------END CERTIFICATE----- - -GlobalSign Root E46 -=================== ------BEGIN CERTIFICATE----- -MIICCzCCAZGgAwIBAgISEdK7ujNu1LzmJGjFDYQdmOhDMAoGCCqGSM49BAMDMEYxCzAJBgNVBAYT -AkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRwwGgYDVQQDExNHbG9iYWxTaWduIFJvb3Qg -RTQ2MB4XDTE5MDMyMDAwMDAwMFoXDTQ2MDMyMDAwMDAwMFowRjELMAkGA1UEBhMCQkUxGTAXBgNV -BAoTEEdsb2JhbFNpZ24gbnYtc2ExHDAaBgNVBAMTE0dsb2JhbFNpZ24gUm9vdCBFNDYwdjAQBgcq -hkjOPQIBBgUrgQQAIgNiAAScDrHPt+ieUnd1NPqlRqetMhkytAepJ8qUuwzSChDH2omwlwxwEwkB -jtjqR+q+soArzfwoDdusvKSGN+1wCAB16pMLey5SnCNoIwZD7JIvU4Tb+0cUB+hflGddyXqBPCCj -QjBAMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBQxCpCPtsad0kRL -gLWi5h+xEk8blTAKBggqhkjOPQQDAwNoADBlAjEA31SQ7Zvvi5QCkxeCmb6zniz2C5GMn0oUsfZk -vLtoURMMA/cVi4RguYv/Uo7njLwcAjA8+RHUjE7AwWHCFUyqqx0LMV87HOIAl0Qx5v5zli/altP+ -CAezNIm8BZ/3Hobui3A= ------END CERTIFICATE----- - -GLOBALTRUST 2020 -================ ------BEGIN CERTIFICATE----- -MIIFgjCCA2qgAwIBAgILWku9WvtPilv6ZeUwDQYJKoZIhvcNAQELBQAwTTELMAkGA1UEBhMCQVQx -IzAhBgNVBAoTGmUtY29tbWVyY2UgbW9uaXRvcmluZyBHbWJIMRkwFwYDVQQDExBHTE9CQUxUUlVT -VCAyMDIwMB4XDTIwMDIxMDAwMDAwMFoXDTQwMDYxMDAwMDAwMFowTTELMAkGA1UEBhMCQVQxIzAh -BgNVBAoTGmUtY29tbWVyY2UgbW9uaXRvcmluZyBHbWJIMRkwFwYDVQQDExBHTE9CQUxUUlVTVCAy -MDIwMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAri5WrRsc7/aVj6B3GyvTY4+ETUWi -D59bRatZe1E0+eyLinjF3WuvvcTfk0Uev5E4C64OFudBc/jbu9G4UeDLgztzOG53ig9ZYybNpyrO -VPu44sB8R85gfD+yc/LAGbaKkoc1DZAoouQVBGM+uq/ufF7MpotQsjj3QWPKzv9pj2gOlTblzLmM -CcpL3TGQlsjMH/1WljTbjhzqLL6FLmPdqqmV0/0plRPwyJiT2S0WR5ARg6I6IqIoV6Lr/sCMKKCm -fecqQjuCgGOlYx8ZzHyyZqjC0203b+J+BlHZRYQfEs4kUmSFC0iAToexIiIwquuuvuAC4EDosEKA -A1GqtH6qRNdDYfOiaxaJSaSjpCuKAsR49GiKweR6NrFvG5Ybd0mN1MkGco/PU+PcF4UgStyYJ9OR -JitHHmkHr96i5OTUawuzXnzUJIBHKWk7buis/UDr2O1xcSvy6Fgd60GXIsUf1DnQJ4+H4xj04KlG -DfV0OoIu0G4skaMxXDtG6nsEEFZegB31pWXogvziB4xiRfUg3kZwhqG8k9MedKZssCz3AwyIDMvU -clOGvGBG85hqwvG/Q/lwIHfKN0F5VVJjjVsSn8VoxIidrPIwq7ejMZdnrY8XD2zHc+0klGvIg5rQ -mjdJBKuxFshsSUktq6HQjJLyQUp5ISXbY9e2nKd+Qmn7OmMCAwEAAaNjMGEwDwYDVR0TAQH/BAUw -AwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFNwuH9FhN3nkq9XVsxJxaD1qaJwiMB8GA1Ud -IwQYMBaAFNwuH9FhN3nkq9XVsxJxaD1qaJwiMA0GCSqGSIb3DQEBCwUAA4ICAQCR8EICaEDuw2jA -VC/f7GLDw56KoDEoqoOOpFaWEhCGVrqXctJUMHytGdUdaG/7FELYjQ7ztdGl4wJCXtzoRlgHNQIw -4Lx0SsFDKv/bGtCwr2zD/cuz9X9tAy5ZVp0tLTWMstZDFyySCstd6IwPS3BD0IL/qMy/pJTAvoe9 -iuOTe8aPmxadJ2W8esVCgmxcB9CpwYhgROmYhRZf+I/KARDOJcP5YBugxZfD0yyIMaK9MOzQ0MAS -8cE54+X1+NZK3TTN+2/BT+MAi1bikvcoskJ3ciNnxz8RFbLEAwW+uxF7Cr+obuf/WEPPm2eggAe2 -HcqtbepBEX4tdJP7wry+UUTF72glJ4DjyKDUEuzZpTcdN3y0kcra1LGWge9oXHYQSa9+pTeAsRxS -vTOBTI/53WXZFM2KJVj04sWDpQmQ1GwUY7VA3+vA/MRYfg0UFodUJ25W5HCEuGwyEn6CMUO+1918 -oa2u1qsgEu8KwxCMSZY13At1XrFP1U80DhEgB3VDRemjEdqso5nCtnkn4rnvyOL2NSl6dPrFf4IF -YqYK6miyeUcGbvJXqBUzxvd4Sj1Ce2t+/vdG6tHrju+IaFvowdlxfv1k7/9nR4hYJS8+hge9+6jl -gqispdNpQ80xiEmEU5LAsTkbOYMBMMTyqfrQA71yN2BWHzZ8vTmR9W0Nv3vXkg== ------END CERTIFICATE----- - -ANF Secure Server Root CA -========================= ------BEGIN CERTIFICATE----- -MIIF7zCCA9egAwIBAgIIDdPjvGz5a7EwDQYJKoZIhvcNAQELBQAwgYQxEjAQBgNVBAUTCUc2MzI4 -NzUxMDELMAkGA1UEBhMCRVMxJzAlBgNVBAoTHkFORiBBdXRvcmlkYWQgZGUgQ2VydGlmaWNhY2lv -bjEUMBIGA1UECxMLQU5GIENBIFJhaXoxIjAgBgNVBAMTGUFORiBTZWN1cmUgU2VydmVyIFJvb3Qg -Q0EwHhcNMTkwOTA0MTAwMDM4WhcNMzkwODMwMTAwMDM4WjCBhDESMBAGA1UEBRMJRzYzMjg3NTEw -MQswCQYDVQQGEwJFUzEnMCUGA1UEChMeQU5GIEF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uMRQw -EgYDVQQLEwtBTkYgQ0EgUmFpejEiMCAGA1UEAxMZQU5GIFNlY3VyZSBTZXJ2ZXIgUm9vdCBDQTCC -AiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANvrayvmZFSVgpCjcqQZAZ2cC4Ffc0m6p6zz -BE57lgvsEeBbphzOG9INgxwruJ4dfkUyYA8H6XdYfp9qyGFOtibBTI3/TO80sh9l2Ll49a2pcbnv -T1gdpd50IJeh7WhM3pIXS7yr/2WanvtH2Vdy8wmhrnZEE26cLUQ5vPnHO6RYPUG9tMJJo8gN0pcv -B2VSAKduyK9o7PQUlrZXH1bDOZ8rbeTzPvY1ZNoMHKGESy9LS+IsJJ1tk0DrtSOOMspvRdOoiXse -zx76W0OLzc2oD2rKDF65nkeP8Nm2CgtYZRczuSPkdxl9y0oukntPLxB3sY0vaJxizOBQ+OyRp1RM -VwnVdmPF6GUe7m1qzwmd+nxPrWAI/VaZDxUse6mAq4xhj0oHdkLePfTdsiQzW7i1o0TJrH93PB0j -7IKppuLIBkwC/qxcmZkLLxCKpvR/1Yd0DVlJRfbwcVw5Kda/SiOL9V8BY9KHcyi1Swr1+KuCLH5z -JTIdC2MKF4EA/7Z2Xue0sUDKIbvVgFHlSFJnLNJhiQcND85Cd8BEc5xEUKDbEAotlRyBr+Qc5RQe -8TZBAQIvfXOn3kLMTOmJDVb3n5HUA8ZsyY/b2BzgQJhdZpmYgG4t/wHFzstGH6wCxkPmrqKEPMVO -Hj1tyRRM4y5Bu8o5vzY8KhmqQYdOpc5LMnndkEl/AgMBAAGjYzBhMB8GA1UdIwQYMBaAFJxf0Gxj -o1+TypOYCK2Mh6UsXME3MB0GA1UdDgQWBBScX9BsY6Nfk8qTmAitjIelLFzBNzAOBgNVHQ8BAf8E -BAMCAYYwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAgEATh65isagmD9uw2nAalxJ -UqzLK114OMHVVISfk/CHGT0sZonrDUL8zPB1hT+L9IBdeeUXZ701guLyPI59WzbLWoAAKfLOKyzx -j6ptBZNscsdW699QIyjlRRA96Gejrw5VD5AJYu9LWaL2U/HANeQvwSS9eS9OICI7/RogsKQOLHDt -dD+4E5UGUcjohybKpFtqFiGS3XNgnhAY3jyB6ugYw3yJ8otQPr0R4hUDqDZ9MwFsSBXXiJCZBMXM -5gf0vPSQ7RPi6ovDj6MzD8EpTBNO2hVWcXNyglD2mjN8orGoGjR0ZVzO0eurU+AagNjqOknkJjCb -5RyKqKkVMoaZkgoQI1YS4PbOTOK7vtuNknMBZi9iPrJyJ0U27U1W45eZ/zo1PqVUSlJZS2Db7v54 -EX9K3BR5YLZrZAPbFYPhor72I5dQ8AkzNqdxliXzuUJ92zg/LFis6ELhDtjTO0wugumDLmsx2d1H -hk9tl5EuT+IocTUW0fJz/iUrB0ckYyfI+PbZa/wSMVYIwFNCr5zQM378BvAxRAMU8Vjq8moNqRGy -g77FGr8H6lnco4g175x2MjxNBiLOFeXdntiP2t7SxDnlF4HPOEfrf4htWRvfn0IUrn7PqLBmZdo3 -r5+qPeoott7VMVgWglvquxl1AnMaykgaIZOQCo6ThKd9OyMYkomgjaw= ------END CERTIFICATE----- - -Certum EC-384 CA -================ ------BEGIN CERTIFICATE----- -MIICZTCCAeugAwIBAgIQeI8nXIESUiClBNAt3bpz9DAKBggqhkjOPQQDAzB0MQswCQYDVQQGEwJQ -TDEhMB8GA1UEChMYQXNzZWNvIERhdGEgU3lzdGVtcyBTLkEuMScwJQYDVQQLEx5DZXJ0dW0gQ2Vy -dGlmaWNhdGlvbiBBdXRob3JpdHkxGTAXBgNVBAMTEENlcnR1bSBFQy0zODQgQ0EwHhcNMTgwMzI2 -MDcyNDU0WhcNNDMwMzI2MDcyNDU0WjB0MQswCQYDVQQGEwJQTDEhMB8GA1UEChMYQXNzZWNvIERh -dGEgU3lzdGVtcyBTLkEuMScwJQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkx -GTAXBgNVBAMTEENlcnR1bSBFQy0zODQgQ0EwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAATEKI6rGFtq -vm5kN2PkzeyrOvfMobgOgknXhimfoZTy42B4mIF4Bk3y7JoOV2CDn7TmFy8as10CW4kjPMIRBSqn -iBMY81CE1700LCeJVf/OTOffph8oxPBUw7l8t1Ot68KjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYD -VR0OBBYEFI0GZnQkdjrzife81r1HfS+8EF9LMA4GA1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAwNo -ADBlAjADVS2m5hjEfO/JUG7BJw+ch69u1RsIGL2SKcHvlJF40jocVYli5RsJHrpka/F2tNQCMQC0 -QoSZ/6vnnvuRlydd3LBbMHHOXjgaatkl5+r3YZJW+OraNsKHZZYuciUvf9/DE8k= ------END CERTIFICATE----- - -Certum Trusted Root CA -====================== ------BEGIN CERTIFICATE----- -MIIFwDCCA6igAwIBAgIQHr9ZULjJgDdMBvfrVU+17TANBgkqhkiG9w0BAQ0FADB6MQswCQYDVQQG -EwJQTDEhMB8GA1UEChMYQXNzZWNvIERhdGEgU3lzdGVtcyBTLkEuMScwJQYDVQQLEx5DZXJ0dW0g -Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkxHzAdBgNVBAMTFkNlcnR1bSBUcnVzdGVkIFJvb3QgQ0Ew -HhcNMTgwMzE2MTIxMDEzWhcNNDMwMzE2MTIxMDEzWjB6MQswCQYDVQQGEwJQTDEhMB8GA1UEChMY -QXNzZWNvIERhdGEgU3lzdGVtcyBTLkEuMScwJQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlvbiBB -dXRob3JpdHkxHzAdBgNVBAMTFkNlcnR1bSBUcnVzdGVkIFJvb3QgQ0EwggIiMA0GCSqGSIb3DQEB -AQUAA4ICDwAwggIKAoICAQDRLY67tzbqbTeRn06TpwXkKQMlzhyC93yZn0EGze2jusDbCSzBfN8p -fktlL5On1AFrAygYo9idBcEq2EXxkd7fO9CAAozPOA/qp1x4EaTByIVcJdPTsuclzxFUl6s1wB52 -HO8AU5853BSlLCIls3Jy/I2z5T4IHhQqNwuIPMqw9MjCoa68wb4pZ1Xi/K1ZXP69VyywkI3C7Te2 -fJmItdUDmj0VDT06qKhF8JVOJVkdzZhpu9PMMsmN74H+rX2Ju7pgE8pllWeg8xn2A1bUatMn4qGt -g/BKEiJ3HAVz4hlxQsDsdUaakFjgao4rpUYwBI4Zshfjvqm6f1bxJAPXsiEodg42MEx51UGamqi4 -NboMOvJEGyCI98Ul1z3G4z5D3Yf+xOr1Uz5MZf87Sst4WmsXXw3Hw09Omiqi7VdNIuJGmj8PkTQk -fVXjjJU30xrwCSss0smNtA0Aq2cpKNgB9RkEth2+dv5yXMSFytKAQd8FqKPVhJBPC/PgP5sZ0jeJ -P/J7UhyM9uH3PAeXjA6iWYEMspA90+NZRu0PqafegGtaqge2Gcu8V/OXIXoMsSt0Puvap2ctTMSY -njYJdmZm/Bo/6khUHL4wvYBQv3y1zgD2DGHZ5yQD4OMBgQ692IU0iL2yNqh7XAjlRICMb/gv1SHK -HRzQ+8S1h9E6Tsd2tTVItQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSM+xx1 -vALTn04uSNn5YFSqxLNP+jAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQENBQADggIBAEii1QAL -LtA/vBzVtVRJHlpr9OTy4EA34MwUe7nJ+jW1dReTagVphZzNTxl4WxmB82M+w85bj/UvXgF2Ez8s -ALnNllI5SW0ETsXpD4YN4fqzX4IS8TrOZgYkNCvozMrnadyHncI013nR03e4qllY/p0m+jiGPp2K -h2RX5Rc64vmNueMzeMGQ2Ljdt4NR5MTMI9UGfOZR0800McD2RrsLrfw9EAUqO0qRJe6M1ISHgCq8 -CYyqOhNf6DR5UMEQGfnTKB7U0VEwKbOukGfWHwpjscWpxkIxYxeU72nLL/qMFH3EQxiJ2fAyQOaA -4kZf5ePBAFmo+eggvIksDkc0C+pXwlM2/KfUrzHN/gLldfq5Jwn58/U7yn2fqSLLiMmq0Uc9Nneo -WWRrJ8/vJ8HjJLWG965+Mk2weWjROeiQWMODvA8s1pfrzgzhIMfatz7DP78v3DSk+yshzWePS/Tj -6tQ/50+6uaWTRRxmHyH6ZF5v4HaUMst19W7l9o/HuKTMqJZ9ZPskWkoDbGs4xugDQ5r3V7mzKWmT -OPQD8rv7gmsHINFSH5pkAnuYZttcTVoP0ISVoDwUQwbKytu4QTbaakRnh6+v40URFWkIsr4WOZck -bxJF0WddCajJFdr60qZfE2Efv4WstK2tBZQIgx51F9NxO5NQI1mg7TyRVJ12AMXDuDjb ------END CERTIFICATE----- - -TunTrust Root CA -================ ------BEGIN CERTIFICATE----- -MIIFszCCA5ugAwIBAgIUEwLV4kBMkkaGFmddtLu7sms+/BMwDQYJKoZIhvcNAQELBQAwYTELMAkG -A1UEBhMCVE4xNzA1BgNVBAoMLkFnZW5jZSBOYXRpb25hbGUgZGUgQ2VydGlmaWNhdGlvbiBFbGVj -dHJvbmlxdWUxGTAXBgNVBAMMEFR1blRydXN0IFJvb3QgQ0EwHhcNMTkwNDI2MDg1NzU2WhcNNDQw -NDI2MDg1NzU2WjBhMQswCQYDVQQGEwJUTjE3MDUGA1UECgwuQWdlbmNlIE5hdGlvbmFsZSBkZSBD -ZXJ0aWZpY2F0aW9uIEVsZWN0cm9uaXF1ZTEZMBcGA1UEAwwQVHVuVHJ1c3QgUm9vdCBDQTCCAiIw -DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMPN0/y9BFPdDCA61YguBUtB9YOCfvdZn56eY+hz -2vYGqU8ftPkLHzmMmiDQfgbU7DTZhrx1W4eI8NLZ1KMKsmwb60ksPqxd2JQDoOw05TDENX37Jk0b -bjBU2PWARZw5rZzJJQRNmpA+TkBuimvNKWfGzC3gdOgFVwpIUPp6Q9p+7FuaDmJ2/uqdHYVy7BG7 -NegfJ7/Boce7SBbdVtfMTqDhuazb1YMZGoXRlJfXyqNlC/M4+QKu3fZnz8k/9YosRxqZbwUN/dAd -gjH8KcwAWJeRTIAAHDOFli/LQcKLEITDCSSJH7UP2dl3RxiSlGBcx5kDPP73lad9UKGAwqmDrViW -VSHbhlnUr8a83YFuB9tgYv7sEG7aaAH0gxupPqJbI9dkxt/con3YS7qC0lH4Zr8GRuR5KiY2eY8f -Tpkdso8MDhz/yV3A/ZAQprE38806JG60hZC/gLkMjNWb1sjxVj8agIl6qeIbMlEsPvLfe/ZdeikZ -juXIvTZxi11Mwh0/rViizz1wTaZQmCXcI/m4WEEIcb9PuISgjwBUFfyRbVinljvrS5YnzWuioYas -DXxU5mZMZl+QviGaAkYt5IPCgLnPSz7ofzwB7I9ezX/SKEIBlYrilz0QIX32nRzFNKHsLA4KUiwS -VXAkPcvCFDVDXSdOvsC9qnyW5/yeYa1E0wCXAgMBAAGjYzBhMB0GA1UdDgQWBBQGmpsfU33x9aTI -04Y+oXNZtPdEITAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFAaamx9TffH1pMjThj6hc1m0 -90QhMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAqgVutt0Vyb+zxiD2BkewhpMl -0425yAA/l/VSJ4hxyXT968pk21vvHl26v9Hr7lxpuhbI87mP0zYuQEkHDVneixCwSQXi/5E/S7fd -Ao74gShczNxtr18UnH1YeA32gAm56Q6XKRm4t+v4FstVEuTGfbvE7Pi1HE4+Z7/FXxttbUcoqgRY -YdZ2vyJ/0Adqp2RT8JeNnYA/u8EH22Wv5psymsNUk8QcCMNE+3tjEUPRahphanltkE8pjkcFwRJp -adbGNjHh/PqAulxPxOu3Mqz4dWEX1xAZufHSCe96Qp1bWgvUxpVOKs7/B9dPfhgGiPEZtdmYu65x -xBzndFlY7wyJz4sfdZMaBBSSSFCp61cpABbjNhzI+L/wM9VBD8TMPN3pM0MBkRArHtG5Xc0yGYuP -jCB31yLEQtyEFpslbei0VXF/sHyz03FJuc9SpAQ/3D2gu68zngowYI7bnV2UqL1g52KAdoGDDIzM -MEZJ4gzSqK/rYXHv5yJiqfdcZGyfFoxnNidF9Ql7v/YQCvGwjVRDjAS6oz/v4jXH+XTgbzRB0L9z -ZVcg+ZtnemZoJE6AZb0QmQZZ8mWvuMZHu/2QeItBcy6vVR/cO5JyboTT0GFMDcx2V+IthSIVNg3r -AZ3r2OvEhJn7wAzMMujjd9qDRIueVSjAi1jTkD5OGwDxFa2DK5o= ------END CERTIFICATE----- - -HARICA TLS RSA Root CA 2021 -=========================== ------BEGIN CERTIFICATE----- -MIIFpDCCA4ygAwIBAgIQOcqTHO9D88aOk8f0ZIk4fjANBgkqhkiG9w0BAQsFADBsMQswCQYDVQQG -EwJHUjE3MDUGA1UECgwuSGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9u -cyBDQTEkMCIGA1UEAwwbSEFSSUNBIFRMUyBSU0EgUm9vdCBDQSAyMDIxMB4XDTIxMDIxOTEwNTUz -OFoXDTQ1MDIxMzEwNTUzN1owbDELMAkGA1UEBhMCR1IxNzA1BgNVBAoMLkhlbGxlbmljIEFjYWRl -bWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgQ0ExJDAiBgNVBAMMG0hBUklDQSBUTFMgUlNB -IFJvb3QgQ0EgMjAyMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAIvC569lmwVnlskN -JLnQDmT8zuIkGCyEf3dRywQRNrhe7Wlxp57kJQmXZ8FHws+RFjZiPTgE4VGC/6zStGndLuwRo0Xu -a2s7TL+MjaQenRG56Tj5eg4MmOIjHdFOY9TnuEFE+2uva9of08WRiFukiZLRgeaMOVig1mlDqa2Y -Ulhu2wr7a89o+uOkXjpFc5gH6l8Cct4MpbOfrqkdtx2z/IpZ525yZa31MJQjB/OCFks1mJxTuy/K -5FrZx40d/JiZ+yykgmvwKh+OC19xXFyuQnspiYHLA6OZyoieC0AJQTPb5lh6/a6ZcMBaD9YThnEv -dmn8kN3bLW7R8pv1GmuebxWMevBLKKAiOIAkbDakO/IwkfN4E8/BPzWr8R0RI7VDIp4BkrcYAuUR -0YLbFQDMYTfBKnya4dC6s1BG7oKsnTH4+yPiAwBIcKMJJnkVU2DzOFytOOqBAGMUuTNe3QvboEUH -GjMJ+E20pwKmafTCWQWIZYVWrkvL4N48fS0ayOn7H6NhStYqE613TBoYm5EPWNgGVMWX+Ko/IIqm -haZ39qb8HOLubpQzKoNQhArlT4b4UEV4AIHrW2jjJo3Me1xR9BQsQL4aYB16cmEdH2MtiKrOokWQ -CPxrvrNQKlr9qEgYRtaQQJKQCoReaDH46+0N0x3GfZkYVVYnZS6NRcUk7M7jAgMBAAGjQjBAMA8G -A1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFApII6ZgpJIKM+qTW8VX6iVNvRLuMA4GA1UdDwEB/wQE -AwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAPpBIqm5iFSVmewzVjIuJndftTgfvnNAUX15QvWiWkKQU -EapobQk1OUAJ2vQJLDSle1mESSmXdMgHHkdt8s4cUCbjnj1AUz/3f5Z2EMVGpdAgS1D0NTsY9FVq -QRtHBmg8uwkIYtlfVUKqrFOFrJVWNlar5AWMxajaH6NpvVMPxP/cyuN+8kyIhkdGGvMA9YCRotxD -QpSbIPDRzbLrLFPCU3hKTwSUQZqPJzLB5UkZv/HywouoCjkxKLR9YjYsTewfM7Z+d21+UPCfDtcR -j88YxeMn/ibvBZ3PzzfF0HvaO7AWhAw6k9a+F9sPPg4ZeAnHqQJyIkv3N3a6dcSFA1pj1bF1BcK5 -vZStjBWZp5N99sXzqnTPBIWUmAD04vnKJGW/4GKvyMX6ssmeVkjaef2WdhW+o45WxLM0/L5H9MG0 -qPzVMIho7suuyWPEdr6sOBjhXlzPrjoiUevRi7PzKzMHVIf6tLITe7pTBGIBnfHAT+7hOtSLIBD6 -Alfm78ELt5BGnBkpjNxvoEppaZS3JGWg/6w/zgH7IS79aPib8qXPMThcFarmlwDB31qlpzmq6YR/ -PFGoOtmUW4y/Twhx5duoXNTSpv4Ao8YWxw/ogM4cKGR0GQjTQuPOAF1/sdwTsOEFy9EgqoZ0njnn -kf3/W9b3raYvAwtt41dU63ZTGI0RmLo= ------END CERTIFICATE----- - -HARICA TLS ECC Root CA 2021 -=========================== ------BEGIN CERTIFICATE----- -MIICVDCCAdugAwIBAgIQZ3SdjXfYO2rbIvT/WeK/zjAKBggqhkjOPQQDAzBsMQswCQYDVQQGEwJH -UjE3MDUGA1UECgwuSGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBD -QTEkMCIGA1UEAwwbSEFSSUNBIFRMUyBFQ0MgUm9vdCBDQSAyMDIxMB4XDTIxMDIxOTExMDExMFoX -DTQ1MDIxMzExMDEwOVowbDELMAkGA1UEBhMCR1IxNzA1BgNVBAoMLkhlbGxlbmljIEFjYWRlbWlj -IGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgQ0ExJDAiBgNVBAMMG0hBUklDQSBUTFMgRUNDIFJv -b3QgQ0EgMjAyMTB2MBAGByqGSM49AgEGBSuBBAAiA2IABDgI/rGgltJ6rK9JOtDA4MM7KKrxcm1l -AEeIhPyaJmuqS7psBAqIXhfyVYf8MLA04jRYVxqEU+kw2anylnTDUR9YSTHMmE5gEYd103KUkE+b -ECUqqHgtvpBBWJAVcqeht6NCMEAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUyRtTgRL+BNUW -0aq8mm+3oJUZbsowDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMDA2cAMGQCMBHervjcToiwqfAi -rcJRQO9gcS3ujwLEXQNwSaSS6sUUiHCm0w2wqsosQJz76YJumgIwK0eaB8bRwoF8yguWGEEbo/Qw -CZ61IygNnxS2PFOiTAZpffpskcYqSUXm7LcT4Tps ------END CERTIFICATE----- - -Autoridad de Certificacion Firmaprofesional CIF A62634068 -========================================================= ------BEGIN CERTIFICATE----- -MIIGFDCCA/ygAwIBAgIIG3Dp0v+ubHEwDQYJKoZIhvcNAQELBQAwUTELMAkGA1UEBhMCRVMxQjBA -BgNVBAMMOUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1hcHJvZmVzaW9uYWwgQ0lGIEE2 -MjYzNDA2ODAeFw0xNDA5MjMxNTIyMDdaFw0zNjA1MDUxNTIyMDdaMFExCzAJBgNVBAYTAkVTMUIw -QAYDVQQDDDlBdXRvcmlkYWQgZGUgQ2VydGlmaWNhY2lvbiBGaXJtYXByb2Zlc2lvbmFsIENJRiBB -NjI2MzQwNjgwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKlmuO6vj78aI14H9M2uDD -Utd9thDIAl6zQyrET2qyyhxdKJp4ERppWVevtSBC5IsP5t9bpgOSL/UR5GLXMnE42QQMcas9UX4P -B99jBVzpv5RvwSmCwLTaUbDBPLutN0pcyvFLNg4kq7/DhHf9qFD0sefGL9ItWY16Ck6WaVICqjaY -7Pz6FIMMNx/Jkjd/14Et5cS54D40/mf0PmbR0/RAz15iNA9wBj4gGFrO93IbJWyTdBSTo3OxDqqH -ECNZXyAFGUftaI6SEspd/NYrspI8IM/hX68gvqB2f3bl7BqGYTM+53u0P6APjqK5am+5hyZvQWyI -plD9amML9ZMWGxmPsu2bm8mQ9QEM3xk9Dz44I8kvjwzRAv4bVdZO0I08r0+k8/6vKtMFnXkIoctX -MbScyJCyZ/QYFpM6/EfY0XiWMR+6KwxfXZmtY4laJCB22N/9q06mIqqdXuYnin1oKaPnirjaEbsX -LZmdEyRG98Xi2J+Of8ePdG1asuhy9azuJBCtLxTa/y2aRnFHvkLfuwHb9H/TKI8xWVvTyQKmtFLK -bpf7Q8UIJm+K9Lv9nyiqDdVF8xM6HdjAeI9BZzwelGSuewvF6NkBiDkal4ZkQdU7hwxu+g/GvUgU -vzlN1J5Bto+WHWOWk9mVBngxaJ43BjuAiUVhOSPHG0SjFeUc+JIwuwIDAQABo4HvMIHsMB0GA1Ud -DgQWBBRlzeurNR4APn7VdMActHNHDhpkLzASBgNVHRMBAf8ECDAGAQH/AgEBMIGmBgNVHSAEgZ4w -gZswgZgGBFUdIAAwgY8wLwYIKwYBBQUHAgEWI2h0dHA6Ly93d3cuZmlybWFwcm9mZXNpb25hbC5j -b20vY3BzMFwGCCsGAQUFBwICMFAeTgBQAGEAcwBlAG8AIABkAGUAIABsAGEAIABCAG8AbgBhAG4A -bwB2AGEAIAA0ADcAIABCAGEAcgBjAGUAbABvAG4AYQAgADAAOAAwADEANzAOBgNVHQ8BAf8EBAMC -AQYwDQYJKoZIhvcNAQELBQADggIBAHSHKAIrdx9miWTtj3QuRhy7qPj4Cx2Dtjqn6EWKB7fgPiDL -4QjbEwj4KKE1soCzC1HA01aajTNFSa9J8OA9B3pFE1r/yJfY0xgsfZb43aJlQ3CTkBW6kN/oGbDb -LIpgD7dvlAceHabJhfa9NPhAeGIQcDq+fUs5gakQ1JZBu/hfHAsdCPKxsIl68veg4MSPi3i1O1il -I45PVf42O+AMt8oqMEEgtIDNrvx2ZnOorm7hfNoD6JQg5iKj0B+QXSBTFCZX2lSX3xZEEAEeiGaP -cjiT3SC3NL7X8e5jjkd5KAb881lFJWAiMxujX6i6KtoaPc1A6ozuBRWV1aUsIC+nmCjuRfzxuIgA -LI9C2lHVnOUTaHFFQ4ueCyE8S1wF3BqfmI7avSKecs2tCsvMo2ebKHTEm9caPARYpoKdrcd7b/+A -lun4jWq9GJAd/0kakFI3ky88Al2CdgtR5xbHV/g4+afNmyJU72OwFW1TZQNKXkqgsqeOSQBZONXH -9IBk9W6VULgRfhVwOEqwf9DEMnDAGf/JOC0ULGb0QkTmVXYbgBVX/8Cnp6o5qtjTcNAuuuuUavpf -NIbnYrX9ivAwhZTJryQCL2/W3Wf+47BVTwSYT6RBVuKT0Gro1vP7ZeDOdcQxWQzugsgMYDNKGbqE -ZycPvEJdvSRUDewdcAZfpLz6IHxV ------END CERTIFICATE----- - -vTrus ECC Root CA -================= ------BEGIN CERTIFICATE----- -MIICDzCCAZWgAwIBAgIUbmq8WapTvpg5Z6LSa6Q75m0c1towCgYIKoZIzj0EAwMwRzELMAkGA1UE -BhMCQ04xHDAaBgNVBAoTE2lUcnVzQ2hpbmEgQ28uLEx0ZC4xGjAYBgNVBAMTEXZUcnVzIEVDQyBS -b290IENBMB4XDTE4MDczMTA3MjY0NFoXDTQzMDczMTA3MjY0NFowRzELMAkGA1UEBhMCQ04xHDAa -BgNVBAoTE2lUcnVzQ2hpbmEgQ28uLEx0ZC4xGjAYBgNVBAMTEXZUcnVzIEVDQyBSb290IENBMHYw -EAYHKoZIzj0CAQYFK4EEACIDYgAEZVBKrox5lkqqHAjDo6LN/llWQXf9JpRCux3NCNtzslt188+c -ToL0v/hhJoVs1oVbcnDS/dtitN9Ti72xRFhiQgnH+n9bEOf+QP3A2MMrMudwpremIFUde4BdS49n -TPEQo0IwQDAdBgNVHQ4EFgQUmDnNvtiyjPeyq+GtJK97fKHbH88wDwYDVR0TAQH/BAUwAwEB/zAO -BgNVHQ8BAf8EBAMCAQYwCgYIKoZIzj0EAwMDaAAwZQIwV53dVvHH4+m4SVBrm2nDb+zDfSXkV5UT -QJtS0zvzQBm8JsctBp61ezaf9SXUY2sAAjEA6dPGnlaaKsyh2j/IZivTWJwghfqrkYpwcBE4YGQL -YgmRWAD5Tfs0aNoJrSEGGJTO ------END CERTIFICATE----- - -vTrus Root CA -============= ------BEGIN CERTIFICATE----- -MIIFVjCCAz6gAwIBAgIUQ+NxE9izWRRdt86M/TX9b7wFjUUwDQYJKoZIhvcNAQELBQAwQzELMAkG -A1UEBhMCQ04xHDAaBgNVBAoTE2lUcnVzQ2hpbmEgQ28uLEx0ZC4xFjAUBgNVBAMTDXZUcnVzIFJv -b3QgQ0EwHhcNMTgwNzMxMDcyNDA1WhcNNDMwNzMxMDcyNDA1WjBDMQswCQYDVQQGEwJDTjEcMBoG -A1UEChMTaVRydXNDaGluYSBDby4sTHRkLjEWMBQGA1UEAxMNdlRydXMgUm9vdCBDQTCCAiIwDQYJ -KoZIhvcNAQEBBQADggIPADCCAgoCggIBAL1VfGHTuB0EYgWgrmy3cLRB6ksDXhA/kFocizuwZots -SKYcIrrVQJLuM7IjWcmOvFjai57QGfIvWcaMY1q6n6MLsLOaXLoRuBLpDLvPbmyAhykUAyyNJJrI -ZIO1aqwTLDPxn9wsYTwaP3BVm60AUn/PBLn+NvqcwBauYv6WTEN+VRS+GrPSbcKvdmaVayqwlHeF -XgQPYh1jdfdr58tbmnDsPmcF8P4HCIDPKNsFxhQnL4Z98Cfe/+Z+M0jnCx5Y0ScrUw5XSmXX+6KA -YPxMvDVTAWqXcoKv8R1w6Jz1717CbMdHflqUhSZNO7rrTOiwCcJlwp2dCZtOtZcFrPUGoPc2BX70 -kLJrxLT5ZOrpGgrIDajtJ8nU57O5q4IikCc9Kuh8kO+8T/3iCiSn3mUkpF3qwHYw03dQ+A0Em5Q2 -AXPKBlim0zvc+gRGE1WKyURHuFE5Gi7oNOJ5y1lKCn+8pu8fA2dqWSslYpPZUxlmPCdiKYZNpGvu -/9ROutW04o5IWgAZCfEF2c6Rsffr6TlP9m8EQ5pV9T4FFL2/s1m02I4zhKOQUqqzApVg+QxMaPnu -1RcN+HFXtSXkKe5lXa/R7jwXC1pDxaWG6iSe4gUH3DRCEpHWOXSuTEGC2/KmSNGzm/MzqvOmwMVO -9fSddmPmAsYiS8GVP1BkLFTltvA8Kc9XAgMBAAGjQjBAMB0GA1UdDgQWBBRUYnBj8XWEQ1iO0RYg -scasGrz2iTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOC -AgEAKbqSSaet8PFww+SX8J+pJdVrnjT+5hpk9jprUrIQeBqfTNqK2uwcN1LgQkv7bHbKJAs5EhWd -nxEt/Hlk3ODg9d3gV8mlsnZwUKT+twpw1aA08XXXTUm6EdGz2OyC/+sOxL9kLX1jbhd47F18iMjr -jld22VkE+rxSH0Ws8HqA7Oxvdq6R2xCOBNyS36D25q5J08FsEhvMKar5CKXiNxTKsbhm7xqC5PD4 -8acWabfbqWE8n/Uxy+QARsIvdLGx14HuqCaVvIivTDUHKgLKeBRtRytAVunLKmChZwOgzoy8sHJn -xDHO2zTlJQNgJXtxmOTAGytfdELSS8VZCAeHvsXDf+eW2eHcKJfWjwXj9ZtOyh1QRwVTsMo554Wg -icEFOwE30z9J4nfrI8iIZjs9OXYhRvHsXyO466JmdXTBQPfYaJqT4i2pLr0cox7IdMakLXogqzu4 -sEb9b91fUlV1YvCXoHzXOP0l382gmxDPi7g4Xl7FtKYCNqEeXxzP4padKar9mK5S4fNBUvupLnKW -nyfjqnN9+BojZns7q2WwMgFLFT49ok8MKzWixtlnEjUwzXYuFrOZnk1PTi07NEPhmg4NpGaXutIc -SkwsKouLgU9xGqndXHt7CMUADTdA43x7VF8vhV929vensBxXVsFy6K2ir40zSbofitzmdHxghm+H -l3s= ------END CERTIFICATE----- - -ISRG Root X2 -============ ------BEGIN CERTIFICATE----- -MIICGzCCAaGgAwIBAgIQQdKd0XLq7qeAwSxs6S+HUjAKBggqhkjOPQQDAzBPMQswCQYDVQQGEwJV -UzEpMCcGA1UEChMgSW50ZXJuZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElT -UkcgUm9vdCBYMjAeFw0yMDA5MDQwMDAwMDBaFw00MDA5MTcxNjAwMDBaME8xCzAJBgNVBAYTAlVT -MSkwJwYDVQQKEyBJbnRlcm5ldCBTZWN1cml0eSBSZXNlYXJjaCBHcm91cDEVMBMGA1UEAxMMSVNS -RyBSb290IFgyMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEzZvVn4CDCuwJSvMWSj5cz3es3mcFDR0H -ttwW+1qLFNvicWDEukWVEYmO6gbf9yoWHKS5xcUy4APgHoIYOIvXRdgKam7mAHf7AlF9ItgKbppb -d9/w+kHsOdx1ymgHDB/qo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV -HQ4EFgQUfEKWrt5LSDv6kviejM9ti6lyN5UwCgYIKoZIzj0EAwMDaAAwZQIwe3lORlCEwkSHRhtF -cP9Ymd70/aTSVaYgLXTWNLxBo1BfASdWtL4ndQavEi51mI38AjEAi/V3bNTIZargCyzuFJ0nN6T5 -U6VR5CmD1/iQMVtCnwr1/q4AaOeMSQ+2b1tbFfLn ------END CERTIFICATE----- - -HiPKI Root CA - G1 -================== ------BEGIN CERTIFICATE----- -MIIFajCCA1KgAwIBAgIQLd2szmKXlKFD6LDNdmpeYDANBgkqhkiG9w0BAQsFADBPMQswCQYDVQQG -EwJUVzEjMCEGA1UECgwaQ2h1bmdod2EgVGVsZWNvbSBDby4sIEx0ZC4xGzAZBgNVBAMMEkhpUEtJ -IFJvb3QgQ0EgLSBHMTAeFw0xOTAyMjIwOTQ2MDRaFw0zNzEyMzExNTU5NTlaME8xCzAJBgNVBAYT -AlRXMSMwIQYDVQQKDBpDaHVuZ2h3YSBUZWxlY29tIENvLiwgTHRkLjEbMBkGA1UEAwwSSGlQS0kg -Um9vdCBDQSAtIEcxMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA9B5/UnMyDHPkvRN0 -o9QwqNCuS9i233VHZvR85zkEHmpwINJaR3JnVfSl6J3VHiGh8Ge6zCFovkRTv4354twvVcg3Px+k -wJyz5HdcoEb+d/oaoDjq7Zpy3iu9lFc6uux55199QmQ5eiY29yTw1S+6lZgRZq2XNdZ1AYDgr/SE -YYwNHl98h5ZeQa/rh+r4XfEuiAU+TCK72h8q3VJGZDnzQs7ZngyzsHeXZJzA9KMuH5UHsBffMNsA -GJZMoYFL3QRtU6M9/Aes1MU3guvklQgZKILSQjqj2FPseYlgSGDIcpJQ3AOPgz+yQlda22rpEZfd -hSi8MEyr48KxRURHH+CKFgeW0iEPU8DtqX7UTuybCeyvQqww1r/REEXgphaypcXTT3OUM3ECoWqj -1jOXTyFjHluP2cFeRXF3D4FdXyGarYPM+l7WjSNfGz1BryB1ZlpK9p/7qxj3ccC2HTHsOyDry+K4 -9a6SsvfhhEvyovKTmiKe0xRvNlS9H15ZFblzqMF8b3ti6RZsR1pl8w4Rm0bZ/W3c1pzAtH2lsN0/ -Vm+h+fbkEkj9Bn8SV7apI09bA8PgcSojt/ewsTu8mL3WmKgMa/aOEmem8rJY5AIJEzypuxC00jBF -8ez3ABHfZfjcK0NVvxaXxA/VLGGEqnKG/uY6fsI/fe78LxQ+5oXdUG+3Se0CAwEAAaNCMEAwDwYD -VR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU8ncX+l6o/vY9cdVouslGDDjYr7AwDgYDVR0PAQH/BAQD -AgGGMA0GCSqGSIb3DQEBCwUAA4ICAQBQUfB13HAE4/+qddRxosuej6ip0691x1TPOhwEmSKsxBHi -7zNKpiMdDg1H2DfHb680f0+BazVP6XKlMeJ45/dOlBhbQH3PayFUhuaVevvGyuqcSE5XCV0vrPSl -tJczWNWseanMX/mF+lLFjfiRFOs6DRfQUsJ748JzjkZ4Bjgs6FzaZsT0pPBWGTMpWmWSBUdGSquE -wx4noR8RkpkndZMPvDY7l1ePJlsMu5wP1G4wB9TcXzZoZjmDlicmisjEOf6aIW/Vcobpf2Lll07Q -JNBAsNB1CI69aO4I1258EHBGG3zgiLKecoaZAeO/n0kZtCW+VmWuF2PlHt/o/0elv+EmBYTksMCv -5wiZqAxeJoBF1PhoL5aPruJKHJwWDBNvOIf2u8g0X5IDUXlwpt/L9ZlNec1OvFefQ05rLisY+Gpz -jLrFNe85akEez3GoorKGB1s6yeHvP2UEgEcyRHCVTjFnanRbEEV16rCf0OY1/k6fi8wrkkVbbiVg -hUbN0aqwdmaTd5a+g744tiROJgvM7XpWGuDpWsZkrUx6AEhEL7lAuxM+vhV4nYWBSipX3tUZQ9rb -yltHhoMLP7YNdnhzeSJesYAfz77RP1YQmCuVh6EfnWQUYDksswBVLuT1sw5XxJFBAJw/6KXf6vb/ -yPCtbVKoF6ubYfwSUTXkJf2vqmqGOQ== ------END CERTIFICATE----- - -GlobalSign ECC Root CA - R4 -=========================== ------BEGIN CERTIFICATE----- -MIIB3DCCAYOgAwIBAgINAgPlfvU/k/2lCSGypjAKBggqhkjOPQQDAjBQMSQwIgYDVQQLExtHbG9i -YWxTaWduIEVDQyBSb290IENBIC0gUjQxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkds -b2JhbFNpZ24wHhcNMTIxMTEzMDAwMDAwWhcNMzgwMTE5MDMxNDA3WjBQMSQwIgYDVQQLExtHbG9i -YWxTaWduIEVDQyBSb290IENBIC0gUjQxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkds -b2JhbFNpZ24wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAS4xnnTj2wlDp8uORkcA6SumuU5BwkW -ymOxuYb4ilfBV85C+nOh92VC/x7BALJucw7/xyHlGKSq2XE/qNS5zowdo0IwQDAOBgNVHQ8BAf8E -BAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUVLB7rUW44kB/+wpu+74zyTyjhNUwCgYI -KoZIzj0EAwIDRwAwRAIgIk90crlgr/HmnKAWBVBfw147bmF0774BxL4YSFlhgjICICadVGNA3jdg -UM/I2O2dgq43mLyjj0xMqTQrbO/7lZsm ------END CERTIFICATE----- - -GTS Root R1 -=========== ------BEGIN CERTIFICATE----- -MIIFVzCCAz+gAwIBAgINAgPlk28xsBNJiGuiFzANBgkqhkiG9w0BAQwFADBHMQswCQYDVQQGEwJV -UzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3Qg -UjEwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAwMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UE -ChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwggIiMA0G -CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2EQKLHuOhd5s73L+UPreVp0A8of2C+X0yBoJx9vaM -f/vo27xqLpeXo4xL+Sv2sfnOhB2x+cWX3u+58qPpvBKJXqeqUqv4IyfLpLGcY9vXmX7wCl7raKb0 -xlpHDU0QM+NOsROjyBhsS+z8CZDfnWQpJSMHobTSPS5g4M/SCYe7zUjwTcLCeoiKu7rPWRnWr4+w -B7CeMfGCwcDfLqZtbBkOtdh+JhpFAz2weaSUKK0PfyblqAj+lug8aJRT7oM6iCsVlgmy4HqMLnXW -nOunVmSPlk9orj2XwoSPwLxAwAtcvfaHszVsrBhQf4TgTM2S0yDpM7xSma8ytSmzJSq0SPly4cpk -9+aCEI3oncKKiPo4Zor8Y/kB+Xj9e1x3+naH+uzfsQ55lVe0vSbv1gHR6xYKu44LtcXFilWr06zq -kUspzBmkMiVOKvFlRNACzqrOSbTqn3yDsEB750Orp2yjj32JgfpMpf/VjsPOS+C12LOORc92wO1A -K/1TD7Cn1TsNsYqiA94xrcx36m97PtbfkSIS5r762DL8EGMUUXLeXdYWk70paDPvOmbsB4om3xPX -V2V4J95eSRQAogB/mqghtqmxlbCluQ0WEdrHbEg8QOB+DVrNVjzRlwW5y0vtOUucxD/SVRNuJLDW -cfr0wbrM7Rv1/oFB2ACYPTrIrnqYNxgFlQIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0T -AQH/BAUwAwEB/zAdBgNVHQ4EFgQU5K8rJnEaK0gnhS9SZizv8IkTcT4wDQYJKoZIhvcNAQEMBQAD -ggIBAJ+qQibbC5u+/x6Wki4+omVKapi6Ist9wTrYggoGxval3sBOh2Z5ofmmWJyq+bXmYOfg6LEe -QkEzCzc9zolwFcq1JKjPa7XSQCGYzyI0zzvFIoTgxQ6KfF2I5DUkzps+GlQebtuyh6f88/qBVRRi -ClmpIgUxPoLW7ttXNLwzldMXG+gnoot7TiYaelpkttGsN/H9oPM47HLwEXWdyzRSjeZ2axfG34ar -J45JK3VmgRAhpuo+9K4l/3wV3s6MJT/KYnAK9y8JZgfIPxz88NtFMN9iiMG1D53Dn0reWVlHxYci -NuaCp+0KueIHoI17eko8cdLiA6EfMgfdG+RCzgwARWGAtQsgWSl4vflVy2PFPEz0tv/bal8xa5me -LMFrUKTX5hgUvYU/Z6tGn6D/Qqc6f1zLXbBwHSs09dR2CQzreExZBfMzQsNhFRAbd03OIozUhfJF -fbdT6u9AWpQKXCBfTkBdYiJ23//OYb2MI3jSNwLgjt7RETeJ9r/tSQdirpLsQBqvFAnZ0E6yove+ -7u7Y/9waLd64NnHi/Hm3lCXRSHNboTXns5lndcEZOitHTtNCjv0xyBZm2tIMPNuzjsmhDYAPexZ3 -FL//2wmUspO8IFgV6dtxQ/PeEMMA3KgqlbbC1j+Qa3bbbP6MvPJwNQzcmRk13NfIRmPVNnGuV/u3 -gm3c ------END CERTIFICATE----- - -GTS Root R2 -=========== ------BEGIN CERTIFICATE----- -MIIFVzCCAz+gAwIBAgINAgPlrsWNBCUaqxElqjANBgkqhkiG9w0BAQwFADBHMQswCQYDVQQGEwJV -UzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3Qg -UjIwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAwMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UE -ChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjIwggIiMA0G -CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDO3v2m++zsFDQ8BwZabFn3GTXd98GdVarTzTukk3Lv -CvptnfbwhYBboUhSnznFt+4orO/LdmgUud+tAWyZH8QiHZ/+cnfgLFuv5AS/T3KgGjSY6Dlo7JUl -e3ah5mm5hRm9iYz+re026nO8/4Piy33B0s5Ks40FnotJk9/BW9BuXvAuMC6C/Pq8tBcKSOWIm8Wb -a96wyrQD8Nr0kLhlZPdcTK3ofmZemde4wj7I0BOdre7kRXuJVfeKH2JShBKzwkCX44ofR5GmdFrS -+LFjKBC4swm4VndAoiaYecb+3yXuPuWgf9RhD1FLPD+M2uFwdNjCaKH5wQzpoeJ/u1U8dgbuak7M -kogwTZq9TwtImoS1mKPV+3PBV2HdKFZ1E66HjucMUQkQdYhMvI35ezzUIkgfKtzra7tEscszcTJG -r61K8YzodDqs5xoic4DSMPclQsciOzsSrZYuxsN2B6ogtzVJV+mSSeh2FnIxZyuWfoqjx5RWIr9q -S34BIbIjMt/kmkRtWVtd9QCgHJvGeJeNkP+byKq0rxFROV7Z+2et1VsRnTKaG73VululycslaVNV -J1zgyjbLiGH7HrfQy+4W+9OmTN6SpdTi3/UGVN4unUu0kzCqgc7dGtxRcw1PcOnlthYhGXmy5okL -dWTK1au8CcEYof/UVKGFPP0UJAOyh9OktwIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0T -AQH/BAUwAwEB/zAdBgNVHQ4EFgQUu//KjiOfT5nK2+JopqUVJxce2Q4wDQYJKoZIhvcNAQEMBQAD -ggIBAB/Kzt3HvqGf2SdMC9wXmBFqiN495nFWcrKeGk6c1SuYJF2ba3uwM4IJvd8lRuqYnrYb/oM8 -0mJhwQTtzuDFycgTE1XnqGOtjHsB/ncw4c5omwX4Eu55MaBBRTUoCnGkJE+M3DyCB19m3H0Q/gxh -swWV7uGugQ+o+MePTagjAiZrHYNSVc61LwDKgEDg4XSsYPWHgJ2uNmSRXbBoGOqKYcl3qJfEycel -/FVL8/B/uWU9J2jQzGv6U53hkRrJXRqWbTKH7QMgyALOWr7Z6v2yTcQvG99fevX4i8buMTolUVVn -jWQye+mew4K6Ki3pHrTgSAai/GevHyICc/sgCq+dVEuhzf9gR7A/Xe8bVr2XIZYtCtFenTgCR2y5 -9PYjJbigapordwj6xLEokCZYCDzifqrXPW+6MYgKBesntaFJ7qBFVHvmJ2WZICGoo7z7GJa7Um8M -7YNRTOlZ4iBgxcJlkoKM8xAfDoqXvneCbT+PHV28SSe9zE8P4c52hgQjxcCMElv924SgJPFI/2R8 -0L5cFtHvma3AH/vLrrw4IgYmZNralw4/KBVEqE8AyvCazM90arQ+POuV7LXTWtiBmelDGDfrs7vR -WGJB82bSj6p4lVQgw1oudCvV0b4YacCs1aTPObpRhANl6WLAYv7YTVWW4tAR+kg0Eeye7QUd5MjW -HYbL ------END CERTIFICATE----- - -GTS Root R3 -=========== ------BEGIN CERTIFICATE----- -MIICCTCCAY6gAwIBAgINAgPluILrIPglJ209ZjAKBggqhkjOPQQDAzBHMQswCQYDVQQGEwJVUzEi -MCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjMw -HhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAwMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZ -R29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjMwdjAQBgcqhkjO -PQIBBgUrgQQAIgNiAAQfTzOHMymKoYTey8chWEGJ6ladK0uFxh1MJ7x/JlFyb+Kf1qPKzEUURout -736GjOyxfi//qXGdGIRFBEFVbivqJn+7kAHjSxm65FSWRQmx1WyRRK2EE46ajA2ADDL24CejQjBA -MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTB8Sa6oC2uhYHP0/Eq -Er24Cmf9vDAKBggqhkjOPQQDAwNpADBmAjEA9uEglRR7VKOQFhG/hMjqb2sXnh5GmCCbn9MN2azT -L818+FsuVbu/3ZL3pAzcMeGiAjEA/JdmZuVDFhOD3cffL74UOO0BzrEXGhF16b0DjyZ+hOXJYKaV -11RZt+cRLInUue4X ------END CERTIFICATE----- - -GTS Root R4 -=========== ------BEGIN CERTIFICATE----- -MIICCTCCAY6gAwIBAgINAgPlwGjvYxqccpBQUjAKBggqhkjOPQQDAzBHMQswCQYDVQQGEwJVUzEi -MCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjQw -HhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAwMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZ -R29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjQwdjAQBgcqhkjO -PQIBBgUrgQQAIgNiAATzdHOnaItgrkO4NcWBMHtLSZ37wWHO5t5GvWvVYRg1rkDdc/eJkTBa6zzu -hXyiQHY7qca4R9gq55KRanPpsXI5nymfopjTX15YhmUPoYRlBtHci8nHc8iMai/lxKvRHYqjQjBA -MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSATNbrdP9JNqPV2Py1 -PsVq8JQdjDAKBggqhkjOPQQDAwNpADBmAjEA6ED/g94D9J+uHXqnLrmvT/aDHQ4thQEd0dlq7A/C -r8deVl5c1RxYIigL9zC2L7F8AjEA8GE8p/SgguMh1YQdc4acLa/KNJvxn7kjNuK8YAOdgLOaVsjh -4rsUecrNIdSUtUlD ------END CERTIFICATE----- - -Telia Root CA v2 -================ ------BEGIN CERTIFICATE----- -MIIFdDCCA1ygAwIBAgIPAWdfJ9b+euPkrL4JWwWeMA0GCSqGSIb3DQEBCwUAMEQxCzAJBgNVBAYT -AkZJMRowGAYDVQQKDBFUZWxpYSBGaW5sYW5kIE95ajEZMBcGA1UEAwwQVGVsaWEgUm9vdCBDQSB2 -MjAeFw0xODExMjkxMTU1NTRaFw00MzExMjkxMTU1NTRaMEQxCzAJBgNVBAYTAkZJMRowGAYDVQQK -DBFUZWxpYSBGaW5sYW5kIE95ajEZMBcGA1UEAwwQVGVsaWEgUm9vdCBDQSB2MjCCAiIwDQYJKoZI -hvcNAQEBBQADggIPADCCAgoCggIBALLQPwe84nvQa5n44ndp586dpAO8gm2h/oFlH0wnrI4AuhZ7 -6zBqAMCzdGh+sq/H1WKzej9Qyow2RCRj0jbpDIX2Q3bVTKFgcmfiKDOlyzG4OiIjNLh9vVYiQJ3q -9HsDrWj8soFPmNB06o3lfc1jw6P23pLCWBnglrvFxKk9pXSW/q/5iaq9lRdU2HhE8Qx3FZLgmEKn -pNaqIJLNwaCzlrI6hEKNfdWV5Nbb6WLEWLN5xYzTNTODn3WhUidhOPFZPY5Q4L15POdslv5e2QJl -tI5c0BE0312/UqeBAMN/mUWZFdUXyApT7GPzmX3MaRKGwhfwAZ6/hLzRUssbkmbOpFPlob/E2wnW -5olWK8jjfN7j/4nlNW4o6GwLI1GpJQXrSPjdscr6bAhR77cYbETKJuFzxokGgeWKrLDiKca5JLNr -RBH0pUPCTEPlcDaMtjNXepUugqD0XBCzYYP2AgWGLnwtbNwDRm41k9V6lS/eINhbfpSQBGq6WT0E -BXWdN6IOLj3rwaRSg/7Qa9RmjtzG6RJOHSpXqhC8fF6CfaamyfItufUXJ63RDolUK5X6wK0dmBR4 -M0KGCqlztft0DbcbMBnEWg4cJ7faGND/isgFuvGqHKI3t+ZIpEYslOqodmJHixBTB0hXbOKSTbau -BcvcwUpej6w9GU7C7WB1K9vBykLVAgMBAAGjYzBhMB8GA1UdIwQYMBaAFHKs5DN5qkWH9v2sHZ7W -xy+G2CQ5MB0GA1UdDgQWBBRyrOQzeapFh/b9rB2e1scvhtgkOTAOBgNVHQ8BAf8EBAMCAQYwDwYD -VR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAgEAoDtZpwmUPjaE0n4vOaWWl/oRrfxn83EJ -8rKJhGdEr7nv7ZbsnGTbMjBvZ5qsfl+yqwE2foH65IRe0qw24GtixX1LDoJt0nZi0f6X+J8wfBj5 -tFJ3gh1229MdqfDBmgC9bXXYfef6xzijnHDoRnkDry5023X4blMMA8iZGok1GTzTyVR8qPAs5m4H -eW9q4ebqkYJpCh3DflminmtGFZhb069GHWLIzoBSSRE/yQQSwxN8PzuKlts8oB4KtItUsiRnDe+C -y748fdHif64W1lZYudogsYMVoe+KTTJvQS8TUoKU1xrBeKJR3Stwbbca+few4GeXVtt8YVMJAygC -QMez2P2ccGrGKMOF6eLtGpOg3kuYooQ+BXcBlj37tCAPnHICehIv1aO6UXivKitEZU61/Qrowc15 -h2Er3oBXRb9n8ZuRXqWk7FlIEA04x7D6w0RtBPV4UBySllva9bguulvP5fBqnUsvWHMtTy3EHD70 -sz+rFQ47GUGKpMFXEmZxTPpT41frYpUJnlTd0cI8Vzy9OK2YZLe4A5pTVmBds9hCG1xLEooc6+t9 -xnppxyd/pPiL8uSUZodL6ZQHCRJ5irLrdATczvREWeAWysUsWNc8e89ihmpQfTU2Zqf7N+cox9jQ -raVplI/owd8k+BsHMYeB2F326CjYSlKArBPuUBQemMc= ------END CERTIFICATE----- - -D-TRUST BR Root CA 1 2020 -========================= ------BEGIN CERTIFICATE----- -MIIC2zCCAmCgAwIBAgIQfMmPK4TX3+oPyWWa00tNljAKBggqhkjOPQQDAzBIMQswCQYDVQQGEwJE -RTEVMBMGA1UEChMMRC1UcnVzdCBHbWJIMSIwIAYDVQQDExlELVRSVVNUIEJSIFJvb3QgQ0EgMSAy -MDIwMB4XDTIwMDIxMTA5NDUwMFoXDTM1MDIxMTA5NDQ1OVowSDELMAkGA1UEBhMCREUxFTATBgNV -BAoTDEQtVHJ1c3QgR21iSDEiMCAGA1UEAxMZRC1UUlVTVCBCUiBSb290IENBIDEgMjAyMDB2MBAG -ByqGSM49AgEGBSuBBAAiA2IABMbLxyjR+4T1mu9CFCDhQ2tuda38KwOE1HaTJddZO0Flax7mNCq7 -dPYSzuht56vkPE4/RAiLzRZxy7+SmfSk1zxQVFKQhYN4lGdnoxwJGT11NIXe7WB9xwy0QVK5buXu -QqOCAQ0wggEJMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFHOREKv/VbNafAkl1bK6CKBrqx9t -MA4GA1UdDwEB/wQEAwIBBjCBxgYDVR0fBIG+MIG7MD6gPKA6hjhodHRwOi8vY3JsLmQtdHJ1c3Qu -bmV0L2NybC9kLXRydXN0X2JyX3Jvb3RfY2FfMV8yMDIwLmNybDB5oHegdYZzbGRhcDovL2RpcmVj -dG9yeS5kLXRydXN0Lm5ldC9DTj1ELVRSVVNUJTIwQlIlMjBSb290JTIwQ0ElMjAxJTIwMjAyMCxP -PUQtVHJ1c3QlMjBHbWJILEM9REU/Y2VydGlmaWNhdGVyZXZvY2F0aW9ubGlzdDAKBggqhkjOPQQD -AwNpADBmAjEAlJAtE/rhY/hhY+ithXhUkZy4kzg+GkHaQBZTQgjKL47xPoFWwKrY7RjEsK70Pvom -AjEA8yjixtsrmfu3Ubgko6SUeho/5jbiA1czijDLgsfWFBHVdWNbFJWcHwHP2NVypw87 ------END CERTIFICATE----- - -D-TRUST EV Root CA 1 2020 -========================= ------BEGIN CERTIFICATE----- -MIIC2zCCAmCgAwIBAgIQXwJB13qHfEwDo6yWjfv/0DAKBggqhkjOPQQDAzBIMQswCQYDVQQGEwJE -RTEVMBMGA1UEChMMRC1UcnVzdCBHbWJIMSIwIAYDVQQDExlELVRSVVNUIEVWIFJvb3QgQ0EgMSAy -MDIwMB4XDTIwMDIxMTEwMDAwMFoXDTM1MDIxMTA5NTk1OVowSDELMAkGA1UEBhMCREUxFTATBgNV -BAoTDEQtVHJ1c3QgR21iSDEiMCAGA1UEAxMZRC1UUlVTVCBFViBSb290IENBIDEgMjAyMDB2MBAG -ByqGSM49AgEGBSuBBAAiA2IABPEL3YZDIBnfl4XoIkqbz52Yv7QFJsnL46bSj8WeeHsxiamJrSc8 -ZRCC/N/DnU7wMyPE0jL1HLDfMxddxfCxivnvubcUyilKwg+pf3VlSSowZ/Rk99Yad9rDwpdhQntJ -raOCAQ0wggEJMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFH8QARY3OqQo5FD4pPfsazK2/umL -MA4GA1UdDwEB/wQEAwIBBjCBxgYDVR0fBIG+MIG7MD6gPKA6hjhodHRwOi8vY3JsLmQtdHJ1c3Qu -bmV0L2NybC9kLXRydXN0X2V2X3Jvb3RfY2FfMV8yMDIwLmNybDB5oHegdYZzbGRhcDovL2RpcmVj -dG9yeS5kLXRydXN0Lm5ldC9DTj1ELVRSVVNUJTIwRVYlMjBSb290JTIwQ0ElMjAxJTIwMjAyMCxP -PUQtVHJ1c3QlMjBHbWJILEM9REU/Y2VydGlmaWNhdGVyZXZvY2F0aW9ubGlzdDAKBggqhkjOPQQD -AwNpADBmAjEAyjzGKnXCXnViOTYAYFqLwZOZzNnbQTs7h5kXO9XMT8oi96CAy/m0sRtW9XLS/BnR -AjEAkfcwkz8QRitxpNA7RJvAKQIFskF3UfN5Wp6OFKBOQtJbgfM0agPnIjhQW+0ZT0MW ------END CERTIFICATE----- - -DigiCert TLS ECC P384 Root G5 -============================= ------BEGIN CERTIFICATE----- -MIICGTCCAZ+gAwIBAgIQCeCTZaz32ci5PhwLBCou8zAKBggqhkjOPQQDAzBOMQswCQYDVQQGEwJV -UzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xJjAkBgNVBAMTHURpZ2lDZXJ0IFRMUyBFQ0MgUDM4 -NCBSb290IEc1MB4XDTIxMDExNTAwMDAwMFoXDTQ2MDExNDIzNTk1OVowTjELMAkGA1UEBhMCVVMx -FzAVBgNVBAoTDkRpZ2lDZXJ0LCBJbmMuMSYwJAYDVQQDEx1EaWdpQ2VydCBUTFMgRUNDIFAzODQg -Um9vdCBHNTB2MBAGByqGSM49AgEGBSuBBAAiA2IABMFEoc8Rl1Ca3iOCNQfN0MsYndLxf3c1Tzvd -lHJS7cI7+Oz6e2tYIOyZrsn8aLN1udsJ7MgT9U7GCh1mMEy7H0cKPGEQQil8pQgO4CLp0zVozptj -n4S1mU1YoI71VOeVyaNCMEAwHQYDVR0OBBYEFMFRRVBZqz7nLFr6ICISB4CIfBFqMA4GA1UdDwEB -/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MAoGCCqGSM49BAMDA2gAMGUCMQCJao1H5+z8blUD2Wds -Jk6Dxv3J+ysTvLd6jLRl0mlpYxNjOyZQLgGheQaRnUi/wr4CMEfDFXuxoJGZSZOoPHzoRgaLLPIx -AJSdYsiJvRmEFOml+wG4DXZDjC5Ty3zfDBeWUA== ------END CERTIFICATE----- - -DigiCert TLS RSA4096 Root G5 -============================ ------BEGIN CERTIFICATE----- -MIIFZjCCA06gAwIBAgIQCPm0eKj6ftpqMzeJ3nzPijANBgkqhkiG9w0BAQwFADBNMQswCQYDVQQG -EwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xJTAjBgNVBAMTHERpZ2lDZXJ0IFRMUyBSU0E0 -MDk2IFJvb3QgRzUwHhcNMjEwMTE1MDAwMDAwWhcNNDYwMTE0MjM1OTU5WjBNMQswCQYDVQQGEwJV -UzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xJTAjBgNVBAMTHERpZ2lDZXJ0IFRMUyBSU0E0MDk2 -IFJvb3QgRzUwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCz0PTJeRGd/fxmgefM1eS8 -7IE+ajWOLrfn3q/5B03PMJ3qCQuZvWxX2hhKuHisOjmopkisLnLlvevxGs3npAOpPxG02C+JFvuU -AT27L/gTBaF4HI4o4EXgg/RZG5Wzrn4DReW+wkL+7vI8toUTmDKdFqgpwgscONyfMXdcvyej/Ces -tyu9dJsXLfKB2l2w4SMXPohKEiPQ6s+d3gMXsUJKoBZMpG2T6T867jp8nVid9E6P/DsjyG244gXa -zOvswzH016cpVIDPRFtMbzCe88zdH5RDnU1/cHAN1DrRN/BsnZvAFJNY781BOHW8EwOVfH/jXOnV -DdXifBBiqmvwPXbzP6PosMH976pXTayGpxi0KcEsDr9kvimM2AItzVwv8n/vFfQMFawKsPHTDU9q -TXeXAaDxZre3zu/O7Oyldcqs4+Fj97ihBMi8ez9dLRYiVu1ISf6nL3kwJZu6ay0/nTvEF+cdLvvy -z6b84xQslpghjLSR6Rlgg/IwKwZzUNWYOwbpx4oMYIwo+FKbbuH2TbsGJJvXKyY//SovcfXWJL5/ -MZ4PbeiPT02jP/816t9JXkGPhvnxd3lLG7SjXi/7RgLQZhNeXoVPzthwiHvOAbWWl9fNff2C+MIk -wcoBOU+NosEUQB+cZtUMCUbW8tDRSHZWOkPLtgoRObqME2wGtZ7P6wIDAQABo0IwQDAdBgNVHQ4E -FgQUUTMc7TZArxfTJc1paPKvTiM+s0EwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8w -DQYJKoZIhvcNAQEMBQADggIBAGCmr1tfV9qJ20tQqcQjNSH/0GEwhJG3PxDPJY7Jv0Y02cEhJhxw -GXIeo8mH/qlDZJY6yFMECrZBu8RHANmfGBg7sg7zNOok992vIGCukihfNudd5N7HPNtQOa27PShN -lnx2xlv0wdsUpasZYgcYQF+Xkdycx6u1UQ3maVNVzDl92sURVXLFO4uJ+DQtpBflF+aZfTCIITfN -MBc9uPK8qHWgQ9w+iUuQrm0D4ByjoJYJu32jtyoQREtGBzRj7TG5BO6jm5qu5jF49OokYTurWGT/ -u4cnYiWB39yhL/btp/96j1EuMPikAdKFOV8BmZZvWltwGUb+hmA+rYAQCd05JS9Yf7vSdPD3Rh9G -OUrYU9DzLjtxpdRv/PNn5AeP3SYZ4Y1b+qOTEZvpyDrDVWiakuFSdjjo4bq9+0/V77PnSIMx8IIh -47a+p6tv75/fTM8BuGJqIz3nCU2AG3swpMPdB380vqQmsvZB6Akd4yCYqjdP//fx4ilwMUc/dNAU -FvohigLVigmUdy7yWSiLfFCSCmZ4OIN1xLVaqBHG5cGdZlXPU8Sv13WFqUITVuwhd4GTWgzqltlJ -yqEI8pc7bZsEGCREjnwB8twl2F6GmrE52/WRMmrRpnCKovfepEWFJqgejF0pW8hL2JpqA15w8oVP -bEtoL8pU9ozaMv7Da4M/OMZ+ ------END CERTIFICATE----- - -Certainly Root R1 -================= ------BEGIN CERTIFICATE----- -MIIFRzCCAy+gAwIBAgIRAI4P+UuQcWhlM1T01EQ5t+AwDQYJKoZIhvcNAQELBQAwPTELMAkGA1UE -BhMCVVMxEjAQBgNVBAoTCUNlcnRhaW5seTEaMBgGA1UEAxMRQ2VydGFpbmx5IFJvb3QgUjEwHhcN -MjEwNDAxMDAwMDAwWhcNNDYwNDAxMDAwMDAwWjA9MQswCQYDVQQGEwJVUzESMBAGA1UEChMJQ2Vy -dGFpbmx5MRowGAYDVQQDExFDZXJ0YWlubHkgUm9vdCBSMTCCAiIwDQYJKoZIhvcNAQEBBQADggIP -ADCCAgoCggIBANA21B/q3avk0bbm+yLA3RMNansiExyXPGhjZjKcA7WNpIGD2ngwEc/csiu+kr+O -5MQTvqRoTNoCaBZ0vrLdBORrKt03H2As2/X3oXyVtwxwhi7xOu9S98zTm/mLvg7fMbedaFySpvXl -8wo0tf97ouSHocavFwDvA5HtqRxOcT3Si2yJ9HiG5mpJoM610rCrm/b01C7jcvk2xusVtyWMOvwl -DbMicyF0yEqWYZL1LwsYpfSt4u5BvQF5+paMjRcCMLT5r3gajLQ2EBAHBXDQ9DGQilHFhiZ5shGI -XsXwClTNSaa/ApzSRKft43jvRl5tcdF5cBxGX1HpyTfcX35pe0HfNEXgO4T0oYoKNp43zGJS4YkN -KPl6I7ENPT2a/Z2B7yyQwHtETrtJ4A5KVpK8y7XdeReJkd5hiXSSqOMyhb5OhaRLWcsrxXiOcVTQ -AjeZjOVJ6uBUcqQRBi8LjMFbvrWhsFNunLhgkR9Za/kt9JQKl7XsxXYDVBtlUrpMklZRNaBA2Cnb -rlJ2Oy0wQJuK0EJWtLeIAaSHO1OWzaMWj/Nmqhexx2DgwUMFDO6bW2BvBlyHWyf5QBGenDPBt+U1 -VwV/J84XIIwc/PH72jEpSe31C4SnT8H2TsIonPru4K8H+zMReiFPCyEQtkA6qyI6BJyLm4SGcprS -p6XEtHWRqSsjAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud -DgQWBBTgqj8ljZ9EXME66C6ud0yEPmcM9DANBgkqhkiG9w0BAQsFAAOCAgEAuVevuBLaV4OPaAsz -HQNTVfSVcOQrPbA56/qJYv331hgELyE03fFo8NWWWt7CgKPBjcZq91l3rhVkz1t5BXdm6ozTaw3d -8VkswTOlMIAVRQdFGjEitpIAq5lNOo93r6kiyi9jyhXWx8bwPWz8HA2YEGGeEaIi1wrykXprOQ4v -MMM2SZ/g6Q8CRFA3lFV96p/2O7qUpUzpvD5RtOjKkjZUbVwlKNrdrRT90+7iIgXr0PK3aBLXWopB -GsaSpVo7Y0VPv+E6dyIvXL9G+VoDhRNCX8reU9ditaY1BMJH/5n9hN9czulegChB8n3nHpDYT3Y+ -gjwN/KUD+nsa2UUeYNrEjvn8K8l7lcUq/6qJ34IxD3L/DCfXCh5WAFAeDJDBlrXYFIW7pw0WwfgH -JBu6haEaBQmAupVjyTrsJZ9/nbqkRxWbRHDxakvWOF5D8xh+UG7pWijmZeZ3Gzr9Hb4DJqPb1OG7 -fpYnKx3upPvaJVQTA945xsMfTZDsjxtK0hzthZU4UHlG1sGQUDGpXJpuHfUzVounmdLyyCwzk5Iw -x06MZTMQZBf9JBeW0Y3COmor6xOLRPIh80oat3df1+2IpHLlOR+Vnb5nwXARPbv0+Em34yaXOp/S -X3z7wJl8OSngex2/DaeP0ik0biQVy96QXr8axGbqwua6OV+KmalBWQewLK8= ------END CERTIFICATE----- - -Certainly Root E1 -================= ------BEGIN CERTIFICATE----- -MIIB9zCCAX2gAwIBAgIQBiUzsUcDMydc+Y2aub/M+DAKBggqhkjOPQQDAzA9MQswCQYDVQQGEwJV -UzESMBAGA1UEChMJQ2VydGFpbmx5MRowGAYDVQQDExFDZXJ0YWlubHkgUm9vdCBFMTAeFw0yMTA0 -MDEwMDAwMDBaFw00NjA0MDEwMDAwMDBaMD0xCzAJBgNVBAYTAlVTMRIwEAYDVQQKEwlDZXJ0YWlu -bHkxGjAYBgNVBAMTEUNlcnRhaW5seSBSb290IEUxMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE3m/4 -fxzf7flHh4axpMCK+IKXgOqPyEpeKn2IaKcBYhSRJHpcnqMXfYqGITQYUBsQ3tA3SybHGWCA6TS9 -YBk2QNYphwk8kXr2vBMj3VlOBF7PyAIcGFPBMdjaIOlEjeR2o0IwQDAOBgNVHQ8BAf8EBAMCAQYw -DwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU8ygYy2R17ikq6+2uI1g4hevIIgcwCgYIKoZIzj0E -AwMDaAAwZQIxALGOWiDDshliTd6wT99u0nCK8Z9+aozmut6Dacpps6kFtZaSF4fC0urQe87YQVt8 -rgIwRt7qy12a7DLCZRawTDBcMPPaTnOGBtjOiQRINzf43TNRnXCve1XYAS59BWQOhriR ------END CERTIFICATE----- - -E-Tugra Global Root CA RSA v3 -============================= ------BEGIN CERTIFICATE----- -MIIF8zCCA9ugAwIBAgIUDU3FzRYilZYIfrgLfxUGNPt5EDQwDQYJKoZIhvcNAQELBQAwgYAxCzAJ -BgNVBAYTAlRSMQ8wDQYDVQQHEwZBbmthcmExGTAXBgNVBAoTEEUtVHVncmEgRUJHIEEuUy4xHTAb -BgNVBAsTFEUtVHVncmEgVHJ1c3QgQ2VudGVyMSYwJAYDVQQDEx1FLVR1Z3JhIEdsb2JhbCBSb290 -IENBIFJTQSB2MzAeFw0yMDAzMTgwOTA3MTdaFw00NTAzMTIwOTA3MTdaMIGAMQswCQYDVQQGEwJU -UjEPMA0GA1UEBxMGQW5rYXJhMRkwFwYDVQQKExBFLVR1Z3JhIEVCRyBBLlMuMR0wGwYDVQQLExRF -LVR1Z3JhIFRydXN0IENlbnRlcjEmMCQGA1UEAxMdRS1UdWdyYSBHbG9iYWwgUm9vdCBDQSBSU0Eg -djMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCiZvCJt3J77gnJY9LTQ91ew6aEOErx -jYG7FL1H6EAX8z3DeEVypi6Q3po61CBxyryfHUuXCscxuj7X/iWpKo429NEvx7epXTPcMHD4QGxL -sqYxYdE0PD0xesevxKenhOGXpOhL9hd87jwH7eKKV9y2+/hDJVDqJ4GohryPUkqWOmAalrv9c/SF -/YP9f4RtNGx/ardLAQO/rWm31zLZ9Vdq6YaCPqVmMbMWPcLzJmAy01IesGykNz709a/r4d+ABs8q -QedmCeFLl+d3vSFtKbZnwy1+7dZ5ZdHPOrbRsV5WYVB6Ws5OUDGAA5hH5+QYfERaxqSzO8bGwzrw -bMOLyKSRBfP12baqBqG3q+Sx6iEUXIOk/P+2UNOMEiaZdnDpwA+mdPy70Bt4znKS4iicvObpCdg6 -04nmvi533wEKb5b25Y08TVJ2Glbhc34XrD2tbKNSEhhw5oBOM/J+JjKsBY04pOZ2PJ8QaQ5tndLB -eSBrW88zjdGUdjXnXVXHt6woq0bM5zshtQoK5EpZ3IE1S0SVEgpnpaH/WwAH0sDM+T/8nzPyAPiM -bIedBi3x7+PmBvrFZhNb/FAHnnGGstpvdDDPk1Po3CLW3iAfYY2jLqN4MpBs3KwytQXk9TwzDdbg -h3cXTJ2w2AmoDVf3RIXwyAS+XF1a4xeOVGNpf0l0ZAWMowIDAQABo2MwYTAPBgNVHRMBAf8EBTAD -AQH/MB8GA1UdIwQYMBaAFLK0ruYt9ybVqnUtdkvAG1Mh0EjvMB0GA1UdDgQWBBSytK7mLfcm1ap1 -LXZLwBtTIdBI7zAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADggIBAImocn+M684uGMQQ -gC0QDP/7FM0E4BQ8Tpr7nym/Ip5XuYJzEmMmtcyQ6dIqKe6cLcwsmb5FJ+Sxce3kOJUxQfJ9emN4 -38o2Fi+CiJ+8EUdPdk3ILY7r3y18Tjvarvbj2l0Upq7ohUSdBm6O++96SmotKygY/r+QLHUWnw/q -ln0F7psTpURs+APQ3SPh/QMSEgj0GDSz4DcLdxEBSL9htLX4GdnLTeqjjO/98Aa1bZL0SmFQhO3s -SdPkvmjmLuMxC1QLGpLWgti2omU8ZgT5Vdps+9u1FGZNlIM7zR6mK7L+d0CGq+ffCsn99t2HVhjY -sCxVYJb6CH5SkPVLpi6HfMsg2wY+oF0Dd32iPBMbKaITVaA9FCKvb7jQmhty3QUBjYZgv6Rn7rWl -DdF/5horYmbDB7rnoEgcOMPpRfunf/ztAmgayncSd6YAVSgU7NbHEqIbZULpkejLPoeJVF3Zr52X -nGnnCv8PWniLYypMfUeUP95L6VPQMPHF9p5J3zugkaOj/s1YzOrfr28oO6Bpm4/srK4rVJ2bBLFH -IK+WEj5jlB0E5y67hscMmoi/dkfv97ALl2bSRM9gUgfh1SxKOidhd8rXj+eHDjD/DLsE4mHDosiX -YY60MGo8bcIHX0pzLz/5FooBZu+6kcpSV3uu1OYP3Qt6f4ueJiDPO++BcYNZ ------END CERTIFICATE----- - -E-Tugra Global Root CA ECC v3 -============================= ------BEGIN CERTIFICATE----- -MIICpTCCAiqgAwIBAgIUJkYZdzHhT28oNt45UYbm1JeIIsEwCgYIKoZIzj0EAwMwgYAxCzAJBgNV -BAYTAlRSMQ8wDQYDVQQHEwZBbmthcmExGTAXBgNVBAoTEEUtVHVncmEgRUJHIEEuUy4xHTAbBgNV -BAsTFEUtVHVncmEgVHJ1c3QgQ2VudGVyMSYwJAYDVQQDEx1FLVR1Z3JhIEdsb2JhbCBSb290IENB -IEVDQyB2MzAeFw0yMDAzMTgwOTQ2NThaFw00NTAzMTIwOTQ2NThaMIGAMQswCQYDVQQGEwJUUjEP -MA0GA1UEBxMGQW5rYXJhMRkwFwYDVQQKExBFLVR1Z3JhIEVCRyBBLlMuMR0wGwYDVQQLExRFLVR1 -Z3JhIFRydXN0IENlbnRlcjEmMCQGA1UEAxMdRS1UdWdyYSBHbG9iYWwgUm9vdCBDQSBFQ0MgdjMw -djAQBgcqhkjOPQIBBgUrgQQAIgNiAASOmCm/xxAeJ9urA8woLNheSBkQKczLWYHMjLiSF4mDKpL2 -w6QdTGLVn9agRtwcvHbB40fQWxPa56WzZkjnIZpKT4YKfWzqTTKACrJ6CZtpS5iB4i7sAnCWH/31 -Rs7K3IKjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAU/4Ixcj75xGZsrTie0bBRiKWQ -zPUwHQYDVR0OBBYEFP+CMXI++cRmbK04ntGwUYilkMz1MA4GA1UdDwEB/wQEAwIBBjAKBggqhkjO -PQQDAwNpADBmAjEA5gVYaWHlLcoNy/EZCL3W/VGSGn5jVASQkZo1kTmZ+gepZpO6yGjUij/67W4W -Aie3AjEA3VoXK3YdZUKWpqxdinlW2Iob35reX8dQj7FbcQwm32pAAOwzkSFxvmjkI6TZraE3 ------END CERTIFICATE----- - -Security Communication RootCA3 -============================== ------BEGIN CERTIFICATE----- -MIIFfzCCA2egAwIBAgIJAOF8N0D9G/5nMA0GCSqGSIb3DQEBDAUAMF0xCzAJBgNVBAYTAkpQMSUw -IwYDVQQKExxTRUNPTSBUcnVzdCBTeXN0ZW1zIENPLixMVEQuMScwJQYDVQQDEx5TZWN1cml0eSBD -b21tdW5pY2F0aW9uIFJvb3RDQTMwHhcNMTYwNjE2MDYxNzE2WhcNMzgwMTE4MDYxNzE2WjBdMQsw -CQYDVQQGEwJKUDElMCMGA1UEChMcU0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEnMCUGA1UE -AxMeU2VjdXJpdHkgQ29tbXVuaWNhdGlvbiBSb290Q0EzMIICIjANBgkqhkiG9w0BAQEFAAOCAg8A -MIICCgKCAgEA48lySfcw3gl8qUCBWNO0Ot26YQ+TUG5pPDXC7ltzkBtnTCHsXzW7OT4rCmDvu20r -hvtxosis5FaU+cmvsXLUIKx00rgVrVH+hXShuRD+BYD5UpOzQD11EKzAlrenfna84xtSGc4RHwsE -NPXY9Wk8d/Nk9A2qhd7gCVAEF5aEt8iKvE1y/By7z/MGTfmfZPd+pmaGNXHIEYBMwXFAWB6+oHP2 -/D5Q4eAvJj1+XCO1eXDe+uDRpdYMQXF79+qMHIjH7Iv10S9VlkZ8WjtYO/u62C21Jdp6Ts9EriGm -npjKIG58u4iFW/vAEGK78vknR+/RiTlDxN/e4UG/VHMgly1s2vPUB6PmudhvrvyMGS7TZ2crldtY -XLVqAvO4g160a75BflcJdURQVc1aEWEhCmHCqYj9E7wtiS/NYeCVvsq1e+F7NGcLH7YMx3weGVPK -p7FKFSBWFHA9K4IsD50VHUeAR/94mQ4xr28+j+2GaR57GIgUssL8gjMunEst+3A7caoreyYn8xrC -3PsXuKHqy6C0rtOUfnrQq8PsOC0RLoi/1D+tEjtCrI8Cbn3M0V9hvqG8OmpI6iZVIhZdXw3/JzOf -GAN0iltSIEdrRU0id4xVJ/CvHozJgyJUt5rQT9nO/NkuHJYosQLTA70lUhw0Zk8jq/R3gpYd0Vcw -CBEF/VfR2ccCAwEAAaNCMEAwHQYDVR0OBBYEFGQUfPxYchamCik0FW8qy7z8r6irMA4GA1UdDwEB -/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBDAUAA4ICAQDcAiMI4u8hOscNtybS -YpOnpSNyByCCYN8Y11StaSWSntkUz5m5UoHPrmyKO1o5yGwBQ8IibQLwYs1OY0PAFNr0Y/Dq9HHu -Tofjcan0yVflLl8cebsjqodEV+m9NU1Bu0soo5iyG9kLFwfl9+qd9XbXv8S2gVj/yP9kaWJ5rW4O -H3/uHWnlt3Jxs/6lATWUVCvAUm2PVcTJ0rjLyjQIUYWg9by0F1jqClx6vWPGOi//lkkZhOpn2ASx -YfQAW0q3nHE3GYV5v4GwxxMOdnE+OoAGrgYWp421wsTL/0ClXI2lyTrtcoHKXJg80jQDdwj98ClZ -XSEIx2C/pHF7uNkegr4Jr2VvKKu/S7XuPghHJ6APbw+LP6yVGPO5DtxnVW5inkYO0QR4ynKudtml -+LLfiAlhi+8kTtFZP1rUPcmTPCtk9YENFpb3ksP+MW/oKjJ0DvRMmEoYDjBU1cXrvMUVnuiZIesn -KwkK2/HmcBhWuwzkvvnoEKQTkrgc4NtnHVMDpCKn3F2SEDzq//wbEBrD2NCcnWXL0CsnMQMeNuE9 -dnUM/0Umud1RvCPHX9jYhxBAEg09ODfnRDwYwFMJZI//1ZqmfHAuc1Uh6N//g7kdPjIe1qZ9LPFm -6Vwdp6POXiUyK+OVrCoHzrQoeIY8LaadTdJ0MN1kURXbg4NR16/9M51NZg== ------END CERTIFICATE----- - -Security Communication ECC RootCA1 -================================== ------BEGIN CERTIFICATE----- -MIICODCCAb6gAwIBAgIJANZdm7N4gS7rMAoGCCqGSM49BAMDMGExCzAJBgNVBAYTAkpQMSUwIwYD -VQQKExxTRUNPTSBUcnVzdCBTeXN0ZW1zIENPLixMVEQuMSswKQYDVQQDEyJTZWN1cml0eSBDb21t -dW5pY2F0aW9uIEVDQyBSb290Q0ExMB4XDTE2MDYxNjA1MTUyOFoXDTM4MDExODA1MTUyOFowYTEL -MAkGA1UEBhMCSlAxJTAjBgNVBAoTHFNFQ09NIFRydXN0IFN5c3RlbXMgQ08uLExURC4xKzApBgNV -BAMTIlNlY3VyaXR5IENvbW11bmljYXRpb24gRUNDIFJvb3RDQTEwdjAQBgcqhkjOPQIBBgUrgQQA -IgNiAASkpW9gAwPDvTH00xecK4R1rOX9PVdu12O/5gSJko6BnOPpR27KkBLIE+CnnfdldB9sELLo -5OnvbYUymUSxXv3MdhDYW72ixvnWQuRXdtyQwjWpS4g8EkdtXP9JTxpKULGjQjBAMB0GA1UdDgQW -BBSGHOf+LaVKiwj+KBH6vqNm+GBZLzAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAK -BggqhkjOPQQDAwNoADBlAjAVXUI9/Lbu9zuxNuie9sRGKEkz0FhDKmMpzE2xtHqiuQ04pV1IKv3L -snNdo4gIxwwCMQDAqy0Obe0YottT6SXbVQjgUMzfRGEWgqtJsLKB7HOHeLRMsmIbEvoWTSVLY70e -N9k= ------END CERTIFICATE----- - -BJCA Global Root CA1 -==================== ------BEGIN CERTIFICATE----- -MIIFdDCCA1ygAwIBAgIQVW9l47TZkGobCdFsPsBsIDANBgkqhkiG9w0BAQsFADBUMQswCQYDVQQG -EwJDTjEmMCQGA1UECgwdQkVJSklORyBDRVJUSUZJQ0FURSBBVVRIT1JJVFkxHTAbBgNVBAMMFEJK -Q0EgR2xvYmFsIFJvb3QgQ0ExMB4XDTE5MTIxOTAzMTYxN1oXDTQ0MTIxMjAzMTYxN1owVDELMAkG -A1UEBhMCQ04xJjAkBgNVBAoMHUJFSUpJTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZMR0wGwYDVQQD -DBRCSkNBIEdsb2JhbCBSb290IENBMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAPFm -CL3ZxRVhy4QEQaVpN3cdwbB7+sN3SJATcmTRuHyQNZ0YeYjjlwE8R4HyDqKYDZ4/N+AZspDyRhyS -sTphzvq3Rp4Dhtczbu33RYx2N95ulpH3134rhxfVizXuhJFyV9xgw8O558dnJCNPYwpj9mZ9S1Wn -P3hkSWkSl+BMDdMJoDIwOvqfwPKcxRIqLhy1BDPapDgRat7GGPZHOiJBhyL8xIkoVNiMpTAK+BcW -yqw3/XmnkRd4OJmtWO2y3syJfQOcs4ll5+M7sSKGjwZteAf9kRJ/sGsciQ35uMt0WwfCyPQ10WRj -eulumijWML3mG90Vr4TqnMfK9Q7q8l0ph49pczm+LiRvRSGsxdRpJQaDrXpIhRMsDQa4bHlW/KNn -MoH1V6XKV0Jp6VwkYe/iMBhORJhVb3rCk9gZtt58R4oRTklH2yiUAguUSiz5EtBP6DF+bHq/pj+b -OT0CFqMYs2esWz8sgytnOYFcuX6U1WTdno9uruh8W7TXakdI136z1C2OVnZOz2nxbkRs1CTqjSSh -GL+9V/6pmTW12xB3uD1IutbB5/EjPtffhZ0nPNRAvQoMvfXnjSXWgXSHRtQpdaJCbPdzied9v3pK -H9MiyRVVz99vfFXQpIsHETdfg6YmV6YBW37+WGgHqel62bno/1Afq8K0wM7o6v0PvY1NuLxxAgMB -AAGjQjBAMB0GA1UdDgQWBBTF7+3M2I0hxkjk49cULqcWk+WYATAPBgNVHRMBAf8EBTADAQH/MA4G -A1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAUoKsITQfI/Ki2Pm4rzc2IInRNwPWaZ+4 -YRC6ojGYWUfo0Q0lHhVBDOAqVdVXUsv45Mdpox1NcQJeXyFFYEhcCY5JEMEE3KliawLwQ8hOnThJ -dMkycFRtwUf8jrQ2ntScvd0g1lPJGKm1Vrl2i5VnZu69mP6u775u+2D2/VnGKhs/I0qUJDAnyIm8 -60Qkmss9vk/Ves6OF8tiwdneHg56/0OGNFK8YT88X7vZdrRTvJez/opMEi4r89fO4aL/3Xtw+zuh -TaRjAv04l5U/BXCga99igUOLtFkNSoxUnMW7gZ/NfaXvCyUeOiDbHPwfmGcCCtRzRBPbUYQaVQNW -4AB+dAb/OMRyHdOoP2gxXdMJxy6MW2Pg6Nwe0uxhHvLe5e/2mXZgLR6UcnHGCyoyx5JO1UbXHfmp -GQrI+pXObSOYqgs4rZpWDW+N8TEAiMEXnM0ZNjX+VVOg4DwzX5Ze4jLp3zO7Bkqp2IRzznfSxqxx -4VyjHQy7Ct9f4qNx2No3WqB4K/TUfet27fJhcKVlmtOJNBir+3I+17Q9eVzYH6Eze9mCUAyTF6ps -3MKCuwJXNq+YJyo5UOGwifUll35HaBC07HPKs5fRJNz2YqAo07WjuGS3iGJCz51TzZm+ZGiPTx4S -SPfSKcOYKMryMguTjClPPGAyzQWWYezyr/6zcCwupvI= ------END CERTIFICATE----- - -BJCA Global Root CA2 -==================== ------BEGIN CERTIFICATE----- -MIICJTCCAaugAwIBAgIQLBcIfWQqwP6FGFkGz7RK6zAKBggqhkjOPQQDAzBUMQswCQYDVQQGEwJD -TjEmMCQGA1UECgwdQkVJSklORyBDRVJUSUZJQ0FURSBBVVRIT1JJVFkxHTAbBgNVBAMMFEJKQ0Eg -R2xvYmFsIFJvb3QgQ0EyMB4XDTE5MTIxOTAzMTgyMVoXDTQ0MTIxMjAzMTgyMVowVDELMAkGA1UE -BhMCQ04xJjAkBgNVBAoMHUJFSUpJTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZMR0wGwYDVQQDDBRC -SkNBIEdsb2JhbCBSb290IENBMjB2MBAGByqGSM49AgEGBSuBBAAiA2IABJ3LgJGNU2e1uVCxA/jl -SR9BIgmwUVJY1is0j8USRhTFiy8shP8sbqjV8QnjAyEUxEM9fMEsxEtqSs3ph+B99iK++kpRuDCK -/eHeGBIK9ke35xe/J4rUQUyWPGCWwf0VHKNCMEAwHQYDVR0OBBYEFNJKsVF/BvDRgh9Obl+rg/xI -1LCRMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMAoGCCqGSM49BAMDA2gAMGUCMBq8 -W9f+qdJUDkpd0m2xQNz0Q9XSSpkZElaA94M04TVOSG0ED1cxMDAtsaqdAzjbBgIxAMvMh1PLet8g -UXOQwKhbYdDFUDn9hf7B43j4ptZLvZuHjw/l1lOWqzzIQNph91Oj9w== ------END CERTIFICATE----- diff --git a/packaging/docker/docker-entrypoint b/packaging/docker/docker-entrypoint deleted file mode 100755 index efb994f00a2..00000000000 --- a/packaging/docker/docker-entrypoint +++ /dev/null @@ -1,33 +0,0 @@ -#!/bin/bash - -set -euo pipefail - -# Add default apm-server arguments. -APM_SERVER="apm-server --environment=container" - -# If no arguments are provided, just run "apm-server". -if [[ $# -eq 0 ]]; then - exec $APM_SERVER -fi - -# Check if the the user has invoked the image with flags. -# eg. "apm-server -c apm-server.yml" -if [[ -z $1 ]] || [[ ${1:0:1} == '-' ]] ; then - exec $APM_SERVER "$@" -else - # The user may be looking for a subcommand, like "apm-server apikey". - subcommands=$(apm-server help \ - | awk 'BEGIN {RS=""; FS="\n"} /Available Commands:/' \ - | awk '/^ / {print $1}') - - # If we _did_ get a subcommand, pass it to apm-server. - for subcommand in $subcommands; do - if [[ $1 == $subcommand ]]; then - exec $APM_SERVER "$@" - fi - done -fi - -# If neither of those worked, then they have specified the binary they want, so -# just do exactly as they say. -exec "$@" diff --git a/packaging/docker/tini-amd64.tar.xz b/packaging/docker/tini-amd64.tar.xz deleted file mode 100644 index 883e222a55a..00000000000 Binary files a/packaging/docker/tini-amd64.tar.xz and /dev/null differ diff --git a/packaging/docker/tini-arm64.tar.xz b/packaging/docker/tini-arm64.tar.xz deleted file mode 100644 index f0b08eb839a..00000000000 Binary files a/packaging/docker/tini-arm64.tar.xz and /dev/null differ diff --git a/packaging/files/linux/apm-server.sh b/packaging/files/linux/apm-server.sh old mode 100644 new mode 100755 diff --git a/packaging/files/linux/postinstall.sh b/packaging/files/linux/postinstall.sh old mode 100644 new mode 100755 diff --git a/packaging/files/linux/preinstall.sh b/packaging/files/linux/preinstall.sh old mode 100644 new mode 100755 diff --git a/packaging/files/windows/install-service.ps1 b/packaging/files/windows/install-service.ps1 index 324127bda8d..e6956d92f70 100644 --- a/packaging/files/windows/install-service.ps1 +++ b/packaging/files/windows/install-service.ps1 @@ -10,8 +10,8 @@ $workdir = Split-Path $MyInvocation.MyCommand.Path # Create the new service. New-Service -name apm-server ` - -displayName {{.BeatName | title}} ` - -binaryPathName "`"$workdir\apm-server.exe`" --environment=windows_service -c `"$workdir\apm-server.yml`" --path.home `"$workdir`" --path.data `"$env:PROGRAMDATA\apm-server`" --path.logs `"$env:PROGRAMDATA\apm-server\logs`" -E logging.files.redirect_stderr=true" + -displayName apm-server` + -binaryPathName "`"$workdir\apm-server.exe`" --environment=windows_service -c `"$workdir\apm-server.yml`" --path.home `"$workdir`" --path.data `"$env:PROGRAMFILES\apm-server`" --path.logs `"$env:PROGRAMFILES\apm-server\logs`" -E logging.files.redirect_stderr=true" # Attempt to set the service to delayed start using sc config. Try { diff --git a/packaging/ironbank/Dockerfile b/packaging/ironbank/Dockerfile index d6090dcdd6f..fda358a5439 100644 --- a/packaging/ironbank/Dockerfile +++ b/packaging/ironbank/Dockerfile @@ -4,7 +4,7 @@ ################################################################################ ARG BASE_REGISTRY=registry1.dsop.io ARG BASE_IMAGE=redhat/ubi/ubi9 -ARG BASE_TAG=9.4 +ARG BASE_TAG=9.5 FROM ${BASE_REGISTRY}/${BASE_IMAGE}:${BASE_TAG} AS prep_files @@ -73,6 +73,6 @@ USER ${ELASTIC_PRODUCT} EXPOSE 8200 # TODO: eventually /tinit will be replaced by /usr/bin/tini ENTRYPOINT ["/tinit", "--", "/usr/share/apm-server/apm-server"] -CMD ["-environment", "container"] +CMD ["--environment", "container"] HEALTHCHECK --interval=10s --timeout=5s --start-period=1m --retries=5 CMD (curl -I -f --max-time 5 https://127.0.0.1:8200 || curl -I -f --max-time 5 http://127.0.0.1:8200 || exit 1) diff --git a/packaging/ironbank/hardening_manifest.yaml b/packaging/ironbank/hardening_manifest.yaml index bb5141b3d77..64396f8e57c 100644 --- a/packaging/ironbank/hardening_manifest.yaml +++ b/packaging/ironbank/hardening_manifest.yaml @@ -1,23 +1,19 @@ --- apiVersion: v1 - # The repository name in registry1, excluding /ironbank/ name: "elastic/apm-server/apm-server" - # List of tags to push for the repository in registry1 # The most specific version should be the first tag and will be shown # on ironbank.dsop.io tags: - "${APM_SERVER_VERSION}" - "latest" - # Build args passed to Dockerfile ARGs args: BASE_IMAGE: "redhat/ubi/ubi9" - BASE_TAG: "9.4" + BASE_TAG: "9.5" ELASTIC_STACK: "${APM_SERVER_VERSION}" ELASTIC_PRODUCT: "apm-server" - # Docker image labels labels: org.opencontainers.image.title: "apm-server" @@ -36,7 +32,6 @@ labels: mil.dso.ironbank.image.type: "commercial" ## Product the image belongs to for grouping multiple images mil.dso.ironbank.product.name: "apm-server" - # List of resources to make available to the offline build context resources: - filename: "apm-server-${APM_SERVER_VERSION}-linux-x86_64.tar.gz" @@ -49,8 +44,6 @@ resources: validation: type: sha256 value: 93dcc18adc78c65a028a84799ecf8ad40c936fdfc5f2a57b1acda5a8117fa82c - - # List of project maintainers maintainers: - email: "ivan.fernandez@elastic.co" diff --git a/release.mk b/release.mk index 9e83e9f584c..7a15a95318c 100644 --- a/release.mk +++ b/release.mk @@ -39,23 +39,26 @@ PROJECT_PATCH_VERSION ?= $(shell echo $(RELEASE_VERSION) | cut -f3 -d.) PROJECT_OWNER ?= elastic RELEASE_TYPE ?= minor +# if gh is installed only +ifneq ($(shell command -v gh 2>/dev/null),) CURRENT_RELEASE ?= $(shell gh release list --exclude-drafts --exclude-pre-releases --repo elastic/apm-server --limit 10 --json tagName --jq '.[].tagName|select(. | startswith("v$(PROJECT_MAJOR_VERSION)"))' | sed 's|v||g' | sort -r | head -n 1) RELEASE_BRANCH ?= $(PROJECT_MAJOR_VERSION).$(PROJECT_MINOR_VERSION) NEXT_PROJECT_MINOR_VERSION ?= $(PROJECT_MAJOR_VERSION).$(shell expr $(PROJECT_MINOR_VERSION) + 1).0 NEXT_RELEASE ?= $(RELEASE_BRANCH).$(shell expr $(PROJECT_PATCH_VERSION) + 1) - BRANCH_PATCH = update-$(NEXT_RELEASE) +endif # for the view commits -# as long as 8.x is the branch to run releases, then the base branch is 8.x -# when 8.x is not available the we should use main as the base branch. +# NOTE: as long as 8.x is the branch to run releases, then we use base branch 8.x +# when 8.x is not available then we use the main base branch. CHANGELOG_BRANCH = 8.x # BASE_BRANCH select by release type (default patch) ifeq ($(RELEASE_TYPE),minor) -# as long as 8.x is the branch to run releases, then the base branch is 8.x -# when 8.x is not available the we should use main as the base branch. +# NOTE: as long as 8.x is the branch to run releases, then we use base branch 8.x +# when 8.x is not available then we use the main base branch. BASE_BRANCH ?= 8.x + UPDATE_MERGIFY = true endif ifeq ($(RELEASE_TYPE),patch) @@ -63,6 +66,12 @@ ifeq ($(RELEASE_TYPE),patch) LATEST_RELEASE ?= $(RELEASE_BRANCH).$(shell expr $(PROJECT_PATCH_VERSION) - 1) endif +ifeq ($(RELEASE_TYPE),major) + BASE_BRANCH ?= main + CHANGELOG_BRANCH = main + UPDATE_MERGIFY = true +endif + ####################### ## Templates ####################### @@ -76,6 +85,9 @@ https://github.com/elastic/apm-server/compare/$(RELEASE_BRANCH)\...$(CHANGELOG_B [float] ==== Breaking Changes +[float] +==== Bug fixes + [float] ==== Deprecations @@ -110,6 +122,9 @@ endef # .PHONY: minor-release minor-release: + @echo "INFO: Create GitHub label backport for the version $(RELEASE_VERSION)" + $(MAKE) create-github-label NAME=backport-$(RELEASE_BRANCH) + @echo "INFO: Create release branch and update new version $(RELEASE_VERSION)" $(MAKE) create-branch NAME=$(RELEASE_BRANCH) BASE=$(BASE_BRANCH) $(MAKE) update-version VERSION=$(RELEASE_VERSION) @@ -117,14 +132,33 @@ minor-release: $(MAKE) create-commit COMMIT_MESSAGE="[Release] update version $(RELEASE_VERSION)" @echo "INFO: Create feature branch and update the versions. Target branch $(RELEASE_BRANCH)" - $(MAKE) create-branch NAME=changelog-$(RELEASE_BRANCH) BASE=$(RELEASE_BRANCH) +# NOTE: as long as 8.x is the branch to run releases, then the base branch is 8.x +# when 8.x is not available the we should use main as the base branch. +# BASE=$(RELEASE_BRANCH) +# Target main and use the backport strategy + $(MAKE) create-branch NAME=changelog-$(RELEASE_BRANCH) BASE=main $(MAKE) update-changelog VERSION=$(RELEASE_BRANCH) $(MAKE) rename-changelog VERSION=$(RELEASE_BRANCH) $(MAKE) create-commit COMMIT_MESSAGE="docs: Update changelogs for $(RELEASE_BRANCH) release" +# NOTE: as long as 8.x is the branch to run releases, then we update mergify +# when 8.x is not available then this conditional and the update-mergify should be removed. +# We use a specific PR for mergify, it used to be part of the `update-` PR but it was separated. +# to support 8.x and main releases. +ifeq ($(UPDATE_MERGIFY),true) + @echo "INFO: Create feature branch for mergify changes. Target branch $(RELEASE_BRANCH)" + $(MAKE) create-branch NAME=mergify-$(RELEASE_BRANCH) BASE=main + $(MAKE) update-mergify VERSION=$(RELEASE_BRANCH) + $(MAKE) create-commit COMMIT_MESSAGE="mergify: update backports for $(RELEASE_BRANCH)" +endif + @echo "INFO: Create feature branch and update the versions. Target branch $(BASE_BRANCH)" $(MAKE) create-branch NAME=update-$(RELEASE_VERSION) BASE=$(BASE_BRANCH) - $(MAKE) update-mergify VERSION=$(RELEASE_BRANCH) +# NOTE: as long as main is the branch to run releases, then we update mergify +# TODO: when 8.x is not available then this conditional should be removed and the update-mergify should be kept. +#ifeq ($(BASE_BRANCH),main) +# $(MAKE) update-mergify VERSION=$(RELEASE_BRANCH) +#endif $(MAKE) update-version VERSION=$(NEXT_PROJECT_MINOR_VERSION) $(MAKE) create-commit COMMIT_MESSAGE="[Release] update version $(NEXT_PROJECT_MINOR_VERSION)" $(MAKE) rename-changelog VERSION=$(RELEASE_BRANCH) @@ -132,8 +166,25 @@ minor-release: @echo "INFO: Push changes to $(PROJECT_OWNER)/apm-server and create the relevant Pull Requests" git push origin $(RELEASE_BRANCH) - $(MAKE) create-pull-request BRANCH=update-$(RELEASE_VERSION) TARGET_BRANCH=$(BASE_BRANCH) TITLE="$(RELEASE_BRANCH): update docs, mergify, versions and changelogs" BODY="Merge as soon as the GitHub checks are green." - $(MAKE) create-pull-request BRANCH=changelog-$(RELEASE_BRANCH) TARGET_BRANCH=$(RELEASE_BRANCH) TITLE="$(RELEASE_BRANCH): update docs" BODY="Merge as soon as $(TARGET_BRANCH) branch is created and the GitHub checks are green." +ifeq ($(UPDATE_MERGIFY),true) + $(MAKE) create-pull-request BRANCH=mergify-$(RELEASE_BRANCH) TARGET_BRANCH=main TITLE="$(RELEASE_BRANCH): mergify" BODY="Merge as soon as the GitHub checks are green." BACKPORT_LABEL=backport-skip +endif + $(MAKE) create-pull-request BRANCH=update-$(RELEASE_VERSION) TARGET_BRANCH=$(BASE_BRANCH) TITLE="$(RELEASE_BRANCH): update docs, versions and changelogs" BODY="Merge as soon as the GitHub checks are green" BACKPORT_LABEL=backport-skip +# NOTE: as long as 8.x is the branch to run releases, then we use main as target with the backport label. +# when 8.x is not available then we use TARGET_BRANCH=$(RELEASE_BRANCH) +ifeq ($(BASE_BRANCH),8.x) + @echo "INFO: As long as 8.x is supported, we need to create a PR also in main" + $(MAKE) create-pull-request BRANCH=changelog-$(RELEASE_BRANCH) TARGET_BRANCH=main TITLE="$(RELEASE_BRANCH): update docs" BODY="Merge as soon as $(TARGET_BRANCH) branch is created and the GitHub checks are green. And the PR in main for the Mergify changes has been merged." BACKPORT_LABEL=backport-$(RELEASE_BRANCH) +endif + +# This is the contract with the GitHub action .github/workflows/run-major-release.yml. +# The GitHub action will provide the below environment variables: +# - RELEASE_VERSION +# +.PHONY: major-release +major-release: +# NOTE: major release uses minor-release with BASE_BRANCH=main and CHANGELOG_BRANCH=main + $(MAKE) minor-release # This is the contract with the GitHub action .github/workflows/run-patch-release.yml # The GitHub action will provide the below environment variables: @@ -148,7 +199,7 @@ patch-release: $(MAKE) update-version-legacy VERSION=$(NEXT_RELEASE) PREVIOUS_VERSION=$(CURRENT_RELEASE) $(MAKE) create-commit COMMIT_MESSAGE="$(RELEASE_BRANCH): update versions to $(RELEASE_VERSION)" @echo "INFO: Push changes to $(PROJECT_OWNER)/apm-server and create the relevant Pull Requests" - $(MAKE) create-pull-request BRANCH=$(BRANCH_PATCH) TARGET_BRANCH=$(RELEASE_BRANCH) TITLE="$(RELEASE_VERSION): update versions" BODY="Merge on request by the Release Manager." + $(MAKE) create-pull-request BRANCH=$(BRANCH_PATCH) TARGET_BRANCH=$(RELEASE_BRANCH) TITLE="$(RELEASE_VERSION): update versions" BODY="Merge on request by the Release Manager." BACKPORT_LABEL=backport-skip ############################################ ## Internal make goals to bump versions @@ -197,7 +248,7 @@ update-mergify: echo ' - name: backport patches to $(VERSION) branch' >> .mergify.yml ; \ echo ' conditions:' >> .mergify.yml; \ echo ' - merged' >> .mergify.yml; \ - echo ' - base=8.x' >> .mergify.yml; \ + echo ' - base=main' >> .mergify.yml; \ echo ' - label=backport-$(VERSION)' >> .mergify.yml; \ echo ' actions:' >> .mergify.yml; \ echo ' backport:' >> .mergify.yml; \ @@ -268,19 +319,34 @@ create-commit: fi @echo "::endgroup::" + +## Create a github label +.PHONY: create-github-label +create-github-label: NAME=$${NAME} +create-github-label: + @echo "::group::create-github-label $(NAME)" + gh label create $(NAME) \ + --description "Automated backport with mergify" \ + --color 0052cc \ + --repo $(PROJECT_OWNER)/apm-server \ + --force + @echo "::endgroup::" + ## @help:create-pull-request:Create pull request .PHONY: create-pull-request -create-pull-request: BRANCH=$${BRANCH} TITLE=$${TITLE} TARGET_BRANCH=$${TARGET_BRANCH} BODY=$${BODY} +create-pull-request: BRANCH=$${BRANCH} TITLE=$${TITLE} TARGET_BRANCH=$${TARGET_BRANCH} BODY=$${BODY} BACKPORT_LABEL=$${BACKPORT_LABEL} create-pull-request: @echo "::group::create-pull-request" git push origin $(BRANCH) + echo "--label $(BACKPORT_LABEL)" gh pr create \ --title "$(TITLE)" \ --body "$(BODY)" \ --base $(TARGET_BRANCH) \ --head $(BRANCH) \ --label 'release' \ + --label "$(BACKPORT_LABEL)" \ --reviewer "$(PROJECT_REVIEWERS)" \ --repo $(PROJECT_OWNER)/apm-server || echo "There is no changes" @echo "::endgroup::" diff --git a/script/build_apm_docs.sh b/script/build_apm_docs.sh old mode 100644 new mode 100755 diff --git a/script/intake-receiver-version.sh b/script/intake-receiver-version.sh old mode 100644 new mode 100755 diff --git a/systemtest/agentconfig_test.go b/systemtest/agentconfig_test.go index 8cd2a8683a7..81c56d7ec7a 100644 --- a/systemtest/agentconfig_test.go +++ b/systemtest/agentconfig_test.go @@ -249,7 +249,7 @@ func TestAgentConfigForbiddenOnInvalidConfig(t *testing.T) { systemtest.InvalidateAPIKeyByName(t, apiKeyName) }) // Create an API Key without agent config read privileges - apiKeyBase64 := createAPIKey(t, apiKeyName, "--sourcemap") + apiKeyBase64 := systemtest.CreateAPIKey(t, apiKeyName, []string{"sourcemap:write"}) apiKeyBytes, err := base64.StdEncoding.DecodeString(apiKeyBase64) require.NoError(t, err) srv := apmservertest.NewUnstartedServerTB(t) diff --git a/systemtest/apikeycmd_test.go b/systemtest/apikeycmd_test.go deleted file mode 100644 index 3bdffc3c8a7..00000000000 --- a/systemtest/apikeycmd_test.go +++ /dev/null @@ -1,269 +0,0 @@ -// Licensed to Elasticsearch B.V. under one or more contributor -// license agreements. See the NOTICE file distributed with -// this work for additional information regarding copyright -// ownership. Elasticsearch B.V. licenses this file to you under -// the Apache License, Version 2.0 (the "License"); you may -// not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -package systemtest_test - -import ( - "bytes" - "context" - "encoding/json" - "io" - "net/http" - "strings" - "testing" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - - "github.com/elastic/apm-tools/pkg/espoll" - "github.com/elastic/go-elasticsearch/v8/esapi" - - "github.com/elastic/apm-server/systemtest" - "github.com/elastic/apm-server/systemtest/apmservertest" -) - -func apiKeyCommand(subcommand string, args ...string) *apmservertest.ServerCmd { - cfg := apmservertest.DefaultConfig() - return apiKeyCommandConfig(cfg, subcommand, args...) -} - -func apiKeyCommandConfig(cfg apmservertest.Config, subcommand string, args ...string) *apmservertest.ServerCmd { - cfgargs, err := cfg.Args() - if err != nil { - panic(err) - } - - var esargs []string - for i := 1; i < len(cfgargs); i += 2 { - if !strings.HasPrefix(cfgargs[i], "output.elasticsearch") { - continue - } - esargs = append(esargs, "-E", cfgargs[i]) - } - - userargs := args - args = append([]string{subcommand}, esargs...) - args = append(args, userargs...) - return apmservertest.ServerCommand(context.Background(), "apikey", args...) -} - -func TestAPIKeyCreate(t *testing.T) { - systemtest.InvalidateAPIKeys(t) - defer systemtest.InvalidateAPIKeys(t) - - cmd := apiKeyCommand("create", "--name", t.Name(), "--json") - out, err := cmd.Output() - require.NoError(t, err) - - attrs := decodeJSONMap(t, bytes.NewReader(out)) - assert.Equal(t, t.Name(), attrs["name"]) - assert.Contains(t, attrs, "id") - assert.Contains(t, attrs, "api_key") - assert.Contains(t, attrs, "credentials") - - es := systemtest.NewElasticsearchClientWithAPIKey(attrs["credentials"].(string)) - assertAuthenticateSucceeds(t, es) - - // Check that the API Key has expected metadata. - type apiKey struct { - ID string `json:"id"` - Metadata map[string]interface{} `json:"metadata"` - } - var resp struct { - APIKeys []apiKey `json:"api_keys"` - } - _, err = systemtest.Elasticsearch.Do(context.Background(), &esapi.SecurityGetAPIKeyRequest{ - ID: attrs["id"].(string), - }, &resp) - require.NoError(t, err) - require.Len(t, resp.APIKeys, 1) - assert.Equal(t, map[string]interface{}{"application": "apm"}, resp.APIKeys[0].Metadata) -} - -func TestAPIKeyCreateExpiration(t *testing.T) { - systemtest.InvalidateAPIKeys(t) - defer systemtest.InvalidateAPIKeys(t) - - cmd := apiKeyCommand("create", "--name", t.Name(), "--json", "--expiration=1d") - out, err := cmd.Output() - require.NoError(t, err) - - attrs := decodeJSONMap(t, bytes.NewReader(out)) - assert.Contains(t, attrs, "expiration") -} - -func TestAPIKeyCreateInvalidUser(t *testing.T) { - // heartbeat_user lacks cluster privileges, and cannot create keys - // beats_user has cluster privileges, but not APM application privileges - for _, username := range []string{"heartbeat_user", "beats_user"} { - cfg := apmservertest.DefaultConfig() - cfg.Output.Elasticsearch.Username = username - cfg.Output.Elasticsearch.Password = "changeme" - - cmd := apiKeyCommandConfig(cfg, "create", "--name", t.Name(), "--json") - out, err := cmd.Output() - require.Error(t, err) - attrs := decodeJSONMap(t, bytes.NewReader(out)) - assert.Regexp(t, username+` is missing the following requested privilege\(s\): .*`, attrs["error"]) - } -} - -func TestAPIKeyInvalidateName(t *testing.T) { - systemtest.InvalidateAPIKeys(t) - defer systemtest.InvalidateAPIKeys(t) - - var clients []*espoll.Client - for i := 0; i < 2; i++ { - cmd := apiKeyCommand("create", "--name", t.Name(), "--json") - out, err := cmd.Output() - require.NoError(t, err) - - attrs := decodeJSONMap(t, bytes.NewReader(out)) - es := systemtest.NewElasticsearchClientWithAPIKey(attrs["credentials"].(string)) - assertAuthenticateSucceeds(t, es) - clients = append(clients, es) - } - - cmd := apiKeyCommand("invalidate", "--name", t.Name(), "--json") - out, err := cmd.Output() - require.NoError(t, err) - - result := decodeJSONMap(t, bytes.NewReader(out)) - assert.Len(t, result["invalidated_api_keys"], 2) - assert.Equal(t, float64(0), result["error_count"]) - - for _, es := range clients { - assertAuthenticateFails(t, es) - } -} - -func TestAPIKeyInvalidateID(t *testing.T) { - systemtest.InvalidateAPIKeys(t) - defer systemtest.InvalidateAPIKeys(t) - - cmd := apiKeyCommand("create", "--json") - out, err := cmd.Output() - require.NoError(t, err) - attrs := decodeJSONMap(t, bytes.NewReader(out)) - - es := systemtest.NewElasticsearchClientWithAPIKey(attrs["credentials"].(string)) - assertAuthenticateSucceeds(t, es) - - // NOTE(axw) it is important to use "--id=" rather than "--id" , - // as API keys may begin with a hyphen and be interpreted as flags. - cmd = apiKeyCommand("invalidate", "--json", "--id="+attrs["id"].(string)) - out, err = cmd.Output() - require.NoError(t, err) - result := decodeJSONMap(t, bytes.NewReader(out)) - - assert.Equal(t, []interface{}{attrs["id"]}, result["invalidated_api_keys"]) - assert.Equal(t, float64(0), result["error_count"]) - assertAuthenticateFails(t, es) -} - -func TestAPIKeyVerify(t *testing.T) { - systemtest.InvalidateAPIKeys(t) - defer systemtest.InvalidateAPIKeys(t) - - cmd := apiKeyCommand("create", "--name", t.Name(), "--json", "--ingest", "--agent-config") - out, err := cmd.Output() - require.NoError(t, err) - attrs := decodeJSONMap(t, bytes.NewReader(out)) - credentials := attrs["credentials"].(string) - - cmd = apiKeyCommand("verify", "--json", "--credentials="+credentials) - out, err = cmd.Output() - require.NoError(t, err) - attrs = decodeJSONMap(t, bytes.NewReader(out)) - assert.Equal(t, map[string]interface{}{ - "event:write": true, - "config_agent:read": true, - "sourcemap:write": false, - }, attrs) - - cmd = apiKeyCommand("verify", "--json", "--credentials="+credentials, "--ingest") - out, err = cmd.Output() - require.NoError(t, err) - attrs = decodeJSONMap(t, bytes.NewReader(out)) - assert.Equal(t, map[string]interface{}{"event:write": true}, attrs) -} - -func TestAPIKeyInfo(t *testing.T) { - systemtest.InvalidateAPIKeys(t) - defer systemtest.InvalidateAPIKeys(t) - - var ids []string - for i := 0; i < 2; i++ { - cmd := apiKeyCommand("create", "--name", t.Name(), "--json", "--ingest", "--agent-config") - out, err := cmd.Output() - require.NoError(t, err) - attrs := decodeJSONMap(t, bytes.NewReader(out)) - ids = append(ids, attrs["id"].(string)) - } - - type apiKey struct { - ID string `json:"id"` - Name string `json:"name"` - } - var result struct { - APIKeys []apiKey `json:"api_keys"` - } - - cmd := apiKeyCommand("info", "--json", "--id="+ids[0]) - out, err := cmd.Output() - require.NoError(t, err) - err = json.Unmarshal(out, &result) - require.NoError(t, err) - assert.Equal(t, []apiKey{{ - ID: ids[0], - Name: t.Name(), - }}, result.APIKeys) - - result.APIKeys = nil - cmd = apiKeyCommand("info", "--json", "--name="+t.Name()) - out, err = cmd.Output() - require.NoError(t, err) - err = json.Unmarshal(out, &result) - require.NoError(t, err) - // Should be at least 2, possibly more; Elasticsearch may - // hold invalidated keys from previous test runs. - assert.GreaterOrEqual(t, len(result.APIKeys), 2) -} - -func assertAuthenticateSucceeds(t testing.TB, es *espoll.Client) { - t.Helper() - resp, err := es.Security.Authenticate() - require.NoError(t, err) - assert.False(t, resp.IsError()) - assert.NoError(t, resp.Body.Close()) -} - -func assertAuthenticateFails(t testing.TB, es *espoll.Client) { - t.Helper() - resp, err := es.Security.Authenticate() - require.NoError(t, err) - assert.True(t, resp.IsError()) - assert.Equal(t, http.StatusUnauthorized, resp.StatusCode) - assert.NoError(t, resp.Body.Close()) -} - -func decodeJSONMap(t *testing.T, r io.Reader) map[string]interface{} { - var m map[string]interface{} - err := json.NewDecoder(r).Decode(&m) - require.NoError(t, err) - return m -} diff --git a/systemtest/approvals/TestErrorIngest.approved.json b/systemtest/approvals/TestErrorIngest.approved.json index c542da40e12..8f1f7bc7c95 100644 --- a/systemtest/approvals/TestErrorIngest.approved.json +++ b/systemtest/approvals/TestErrorIngest.approved.json @@ -76,7 +76,7 @@ "logs" ], "error.grouping_key": [ - "d6b3f958dfea98dc9ed2b57d5f0c48bb" + "5be7ecce1b964f32" ], "error.grouping_name": [ "Cannot read property 'baz' of undefined" diff --git a/systemtest/approvals/TestIntake/Errors.approved.json b/systemtest/approvals/TestIntake/Errors.approved.json index 3e1e159693e..6c8576b72ba 100644 --- a/systemtest/approvals/TestIntake/Errors.approved.json +++ b/systemtest/approvals/TestIntake/Errors.approved.json @@ -118,7 +118,7 @@ "ConnectionError" ], "error.grouping_key": [ - "d72b25a26fde3f3aaad1c86950acd070" + "637be2ded470655b" ], "error.grouping_name": [ "My service could not talk to the database named foobar" @@ -439,7 +439,7 @@ "Cannot read property 'baz' no defined" ], "error.grouping_key": [ - "ae0232fed4cb40e7ebc62a585a421d60" + "89f9636ef3381842" ], "error.grouping_name": [ "Cannot read property 'baz' no defined" @@ -655,7 +655,7 @@ "logs" ], "error.grouping_key": [ - "dc8dd667f7036ec5f0bae87bf2188243" + "256d70df2f0019ed" ], "error.grouping_name": [ "no user found" @@ -663,6 +663,9 @@ "error.id": [ "xFoaabb123FFFFFF" ], + "error.log.level": [ + "error" + ], "error.log.message": [ "no user found" ], @@ -877,7 +880,7 @@ "DbError" ], "error.grouping_key": [ - "c3868d6704b923014eaffea034e70a3d" + "60b29d2f9dafe754" ], "error.id": [ "cdefab0123456780" @@ -1093,7 +1096,7 @@ "logs" ], "error.grouping_key": [ - "d6b3f958dfea98dc9ed2b57d5f0c48bb" + "5be7ecce1b964f32" ], "error.grouping_name": [ "Cannot read property 'baz' of undefined" diff --git a/systemtest/approvals/TestIntake/ErrorsTxID.approved.json b/systemtest/approvals/TestIntake/ErrorsTxID.approved.json index 79c6cd3834d..c0aafa59d1c 100644 --- a/systemtest/approvals/TestIntake/ErrorsTxID.approved.json +++ b/systemtest/approvals/TestIntake/ErrorsTxID.approved.json @@ -58,7 +58,7 @@ "ConnectionError" ], "error.grouping_key": [ - "9a4054e958afe722b5877e8fac578ff3" + "676837116a6f59d2" ], "error.grouping_name": [ "Request method 'POST' not supported" diff --git a/systemtest/approvals/TestIntake/Events.approved.json b/systemtest/approvals/TestIntake/Events.approved.json index 9ccf5a3a4be..09ccd8687e2 100644 --- a/systemtest/approvals/TestIntake/Events.approved.json +++ b/systemtest/approvals/TestIntake/Events.approved.json @@ -61,7 +61,7 @@ "ConnectionError" ], "error.grouping_key": [ - "9a4054e958afe722b5877e8fac578ff3" + "676837116a6f59d2" ], "error.grouping_name": [ "Request method 'POST' not supported" diff --git a/systemtest/approvals/TestIntake/MinimalEvents.approved.json b/systemtest/approvals/TestIntake/MinimalEvents.approved.json index 2913f24e4cb..3561ee956ca 100644 --- a/systemtest/approvals/TestIntake/MinimalEvents.approved.json +++ b/systemtest/approvals/TestIntake/MinimalEvents.approved.json @@ -22,7 +22,7 @@ "logs" ], "error.grouping_key": [ - "0b9cba09845a097a271c6beb4c6207f3" + "e7427150b064c482" ], "error.grouping_name": [ "error log message" @@ -30,6 +30,9 @@ "error.id": [ "abcdef0123456789" ], + "error.log.level": [ + "error" + ], "error.log.message": [ "error log message" ], @@ -87,7 +90,7 @@ "error exception message" ], "error.grouping_key": [ - "3a1fb5609458fbb132b44d8fc7cde104" + "5914882bfc6424ff" ], "error.grouping_name": [ "error exception message" @@ -149,7 +152,7 @@ "error exception type" ], "error.grouping_key": [ - "fa405fa2bd848dab17207e7b544d9ad4" + "0726afd6fffc5433" ], "error.id": [ "abcdef0123456791" diff --git a/systemtest/approvals/TestJaeger/batch_0.approved.json b/systemtest/approvals/TestJaeger/batch_0.approved.json deleted file mode 100644 index 61880ba7325..00000000000 --- a/systemtest/approvals/TestJaeger/batch_0.approved.json +++ /dev/null @@ -1,703 +0,0 @@ -[ - { - "@timestamp": [ - "2019-12-20T07:41:45.007Z" - ], - "agent.ephemeral_id": [ - "624386e9c81d2980" - ], - "agent.name": [ - "Jaeger/Go" - ], - "agent.name.text": [ - "Jaeger/Go" - ], - "agent.version": [ - "2.20.1" - ], - "data_stream.dataset": [ - "apm.error" - ], - "data_stream.namespace": [ - "default" - ], - "data_stream.type": [ - "logs" - ], - "error.exception.message": [ - "redis timeout" - ], - "error.grouping_key": [ - "dd09a7d0d9dde0adfcd694967c5a88de" - ], - "error.grouping_name": [ - "Retrying GetDriver after error" - ], - "error.id": [ - "dynamic" - ], - "error.log.message": [ - "Retrying GetDriver after error" - ], - "host.hostname": [ - "host01" - ], - "host.ip": [ - "10.0.0.13" - ], - "host.name": [ - "host01" - ], - "host.name.text": [ - "host01" - ], - "message": [ - "Retrying GetDriver after error" - ], - "observer.hostname": [ - "dynamic" - ], - "observer.type": [ - "apm-server" - ], - "observer.version": [ - "dynamic" - ], - "parent.id": [ - "7be2fd98d0973be3" - ], - "processor.event": [ - "error" - ], - "service.language.name": [ - "Go" - ], - "service.language.name.text": [ - "Go" - ], - "service.name": [ - "driver" - ], - "service.name.text": [ - "driver" - ], - "service.node.name": [ - "host01" - ], - "service.node.name.text": [ - "host01" - ], - "span.id": [ - "7be2fd98d0973be3" - ], - "timestamp.us": [ - 1576827705007552 - ], - "trace.id": [ - "00000000000000007be2fd98d0973be3" - ], - "transaction.id": [ - "7be2fd98d0973be3" - ], - "transaction.sampled": [ - true - ], - "transaction.type": [ - "unknown" - ] - }, - { - "@timestamp": [ - "2019-12-20T07:41:45.089Z" - ], - "agent.ephemeral_id": [ - "624386e9c81d2980" - ], - "agent.name": [ - "Jaeger/Go" - ], - "agent.name.text": [ - "Jaeger/Go" - ], - "agent.version": [ - "2.20.1" - ], - "data_stream.dataset": [ - "apm.error" - ], - "data_stream.namespace": [ - "default" - ], - "data_stream.type": [ - "logs" - ], - "error.exception.message": [ - "redis timeout" - ], - "error.grouping_key": [ - "dd09a7d0d9dde0adfcd694967c5a88de" - ], - "error.grouping_name": [ - "Retrying GetDriver after error" - ], - "error.id": [ - "dynamic" - ], - "error.log.message": [ - "Retrying GetDriver after error" - ], - "host.hostname": [ - "host01" - ], - "host.ip": [ - "10.0.0.13" - ], - "host.name": [ - "host01" - ], - "host.name.text": [ - "host01" - ], - "message": [ - "Retrying GetDriver after error" - ], - "observer.hostname": [ - "dynamic" - ], - "observer.type": [ - "apm-server" - ], - "observer.version": [ - "dynamic" - ], - "parent.id": [ - "7be2fd98d0973be3" - ], - "processor.event": [ - "error" - ], - "service.language.name": [ - "Go" - ], - "service.language.name.text": [ - "Go" - ], - "service.name": [ - "driver" - ], - "service.name.text": [ - "driver" - ], - "service.node.name": [ - "host01" - ], - "service.node.name.text": [ - "host01" - ], - "span.id": [ - "7be2fd98d0973be3" - ], - "timestamp.us": [ - 1576827705089431 - ], - "trace.id": [ - "00000000000000007be2fd98d0973be3" - ], - "transaction.id": [ - "7be2fd98d0973be3" - ], - "transaction.sampled": [ - true - ], - "transaction.type": [ - "unknown" - ] - }, - { - "@timestamp": [ - "2019-12-20T07:41:45.172Z" - ], - "agent.ephemeral_id": [ - "624386e9c81d2980" - ], - "agent.name": [ - "Jaeger/Go" - ], - "agent.name.text": [ - "Jaeger/Go" - ], - "agent.version": [ - "2.20.1" - ], - "data_stream.dataset": [ - "apm.error" - ], - "data_stream.namespace": [ - "default" - ], - "data_stream.type": [ - "logs" - ], - "error.exception.message": [ - "redis timeout" - ], - "error.grouping_key": [ - "dd09a7d0d9dde0adfcd694967c5a88de" - ], - "error.grouping_name": [ - "Retrying GetDriver after error" - ], - "error.id": [ - "dynamic" - ], - "error.log.message": [ - "Retrying GetDriver after error" - ], - "host.hostname": [ - "host01" - ], - "host.ip": [ - "10.0.0.13" - ], - "host.name": [ - "host01" - ], - "host.name.text": [ - "host01" - ], - "message": [ - "Retrying GetDriver after error" - ], - "observer.hostname": [ - "dynamic" - ], - "observer.type": [ - "apm-server" - ], - "observer.version": [ - "dynamic" - ], - "parent.id": [ - "7be2fd98d0973be3" - ], - "processor.event": [ - "error" - ], - "service.language.name": [ - "Go" - ], - "service.language.name.text": [ - "Go" - ], - "service.name": [ - "driver" - ], - "service.name.text": [ - "driver" - ], - "service.node.name": [ - "host01" - ], - "service.node.name.text": [ - "host01" - ], - "span.id": [ - "7be2fd98d0973be3" - ], - "timestamp.us": [ - 1576827705172530 - ], - "trace.id": [ - "00000000000000007be2fd98d0973be3" - ], - "transaction.id": [ - "7be2fd98d0973be3" - ], - "transaction.sampled": [ - true - ], - "transaction.type": [ - "unknown" - ] - }, - { - "@timestamp": [ - "2019-12-20T07:41:45.197Z" - ], - "agent.ephemeral_id": [ - "624386e9c81d2980" - ], - "agent.name": [ - "Jaeger/Go" - ], - "agent.name.text": [ - "Jaeger/Go" - ], - "agent.version": [ - "2.20.1" - ], - "data_stream.dataset": [ - "apm.app.driver" - ], - "data_stream.namespace": [ - "default" - ], - "data_stream.type": [ - "logs" - ], - "event.kind": [ - "event" - ], - "host.hostname": [ - "host01" - ], - "host.ip": [ - "10.0.0.13" - ], - "host.name": [ - "host01" - ], - "host.name.text": [ - "host01" - ], - "labels.level": [ - "info" - ], - "message": [ - "Search successful" - ], - "numeric_labels.num_drivers": [ - 10 - ], - "observer.hostname": [ - "dynamic" - ], - "observer.type": [ - "apm-server" - ], - "observer.version": [ - "dynamic" - ], - "service.language.name": [ - "Go" - ], - "service.language.name.text": [ - "Go" - ], - "service.name": [ - "driver" - ], - "service.name.text": [ - "driver" - ], - "service.node.name": [ - "host01" - ], - "service.node.name.text": [ - "host01" - ], - "span.id": [ - "7be2fd98d0973be3" - ], - "trace.id": [ - "00000000000000007be2fd98d0973be3" - ], - "transaction.id": [ - "7be2fd98d0973be3" - ] - }, - { - "@timestamp": [ - "2019-12-20T07:41:44.954Z" - ], - "agent.ephemeral_id": [ - "624386e9c81d2980" - ], - "agent.name": [ - "Jaeger/Go" - ], - "agent.name.text": [ - "Jaeger/Go" - ], - "agent.version": [ - "2.20.1" - ], - "data_stream.dataset": [ - "apm.app.driver" - ], - "data_stream.namespace": [ - "default" - ], - "data_stream.type": [ - "logs" - ], - "event.kind": [ - "event" - ], - "host.hostname": [ - "host01" - ], - "host.ip": [ - "10.0.0.13" - ], - "host.name": [ - "host01" - ], - "host.name.text": [ - "host01" - ], - "labels.level": [ - "info" - ], - "labels.location": [ - "728,326" - ], - "message": [ - "Searching for nearby drivers" - ], - "observer.hostname": [ - "dynamic" - ], - "observer.type": [ - "apm-server" - ], - "observer.version": [ - "dynamic" - ], - "service.language.name": [ - "Go" - ], - "service.language.name.text": [ - "Go" - ], - "service.name": [ - "driver" - ], - "service.name.text": [ - "driver" - ], - "service.node.name": [ - "host01" - ], - "service.node.name.text": [ - "host01" - ], - "span.id": [ - "7be2fd98d0973be3" - ], - "trace.id": [ - "00000000000000007be2fd98d0973be3" - ], - "transaction.id": [ - "7be2fd98d0973be3" - ] - }, - { - "@timestamp": [ - "2019-12-20T07:41:44.954Z" - ], - "agent.ephemeral_id": [ - "624386e9c81d2980" - ], - "agent.name": [ - "Jaeger/Go" - ], - "agent.name.text": [ - "Jaeger/Go" - ], - "agent.version": [ - "2.20.1" - ], - "data_stream.dataset": [ - "apm.app.driver" - ], - "data_stream.namespace": [ - "default" - ], - "data_stream.type": [ - "logs" - ], - "event.kind": [ - "event" - ], - "host.hostname": [ - "host01" - ], - "host.ip": [ - "10.0.0.13" - ], - "host.name": [ - "host01" - ], - "host.name.text": [ - "host01" - ], - "labels.key": [ - "customer" - ], - "labels.value": [ - "Japanese Desserts" - ], - "message": [ - "baggage" - ], - "observer.hostname": [ - "dynamic" - ], - "observer.type": [ - "apm-server" - ], - "observer.version": [ - "dynamic" - ], - "service.language.name": [ - "Go" - ], - "service.language.name.text": [ - "Go" - ], - "service.name": [ - "driver" - ], - "service.name.text": [ - "driver" - ], - "service.node.name": [ - "host01" - ], - "service.node.name.text": [ - "host01" - ], - "span.id": [ - "7be2fd98d0973be3" - ], - "trace.id": [ - "00000000000000007be2fd98d0973be3" - ], - "transaction.id": [ - "7be2fd98d0973be3" - ] - }, - { - "@timestamp": [ - "2019-12-20T07:41:44.953Z" - ], - "agent.ephemeral_id": [ - "624386e9c81d2980" - ], - "agent.name": [ - "Jaeger/Go" - ], - "agent.name.text": [ - "Jaeger/Go" - ], - "agent.version": [ - "2.20.1" - ], - "data_stream.dataset": [ - "apm" - ], - "data_stream.namespace": [ - "default" - ], - "data_stream.type": [ - "traces" - ], - "event.outcome": [ - "success" - ], - "event.success_count": [ - 1 - ], - "host.hostname": [ - "host01" - ], - "host.ip": [ - "10.0.0.13" - ], - "host.name": [ - "host01" - ], - "host.name.text": [ - "host01" - ], - "labels.as": [ - "thrift" - ], - "labels.peer_service": [ - "driver-client" - ], - "labels.sampler_param": [ - "true" - ], - "labels.sampler_type": [ - "const" - ], - "numeric_labels.peer_ipv4": [ - 2130706433 - ], - "numeric_labels.peer_port": [ - 50535 - ], - "observer.hostname": [ - "dynamic" - ], - "observer.type": [ - "apm-server" - ], - "observer.version": [ - "dynamic" - ], - "processor.event": [ - "transaction" - ], - "service.language.name": [ - "Go" - ], - "service.language.name.text": [ - "Go" - ], - "service.name": [ - "driver" - ], - "service.name.text": [ - "driver" - ], - "service.node.name": [ - "host01" - ], - "service.node.name.text": [ - "host01" - ], - "span.id": [ - "7be2fd98d0973be3" - ], - "timestamp.us": [ - 1576827704953864 - ], - "trace.id": [ - "00000000000000007be2fd98d0973be3" - ], - "transaction.duration.us": [ - 243417 - ], - "transaction.id": [ - "7be2fd98d0973be3" - ], - "transaction.name": [ - "Driver::findNearest" - ], - "transaction.name.text": [ - "Driver::findNearest" - ], - "transaction.result": [ - "Success" - ], - "transaction.sampled": [ - true - ], - "transaction.type": [ - "unknown" - ] - } -] diff --git a/systemtest/approvals/TestJaeger/batch_1.approved.json b/systemtest/approvals/TestJaeger/batch_1.approved.json deleted file mode 100644 index 8ef1664d912..00000000000 --- a/systemtest/approvals/TestJaeger/batch_1.approved.json +++ /dev/null @@ -1,1835 +0,0 @@ -[ - { - "@timestamp": [ - "2019-12-20T07:41:45.006Z" - ], - "agent.ephemeral_id": [ - "2e3f8db3eb77fae0" - ], - "agent.name": [ - "Jaeger/Go" - ], - "agent.name.text": [ - "Jaeger/Go" - ], - "agent.version": [ - "2.20.1" - ], - "data_stream.dataset": [ - "apm.error" - ], - "data_stream.namespace": [ - "default" - ], - "data_stream.type": [ - "logs" - ], - "error.exception.message": [ - "redis timeout" - ], - "error.grouping_key": [ - "dd09a7d0d9dde0adfcd694967c5a88de" - ], - "error.grouping_name": [ - "redis timeout" - ], - "error.id": [ - "dynamic" - ], - "error.log.message": [ - "redis timeout" - ], - "host.hostname": [ - "host01" - ], - "host.ip": [ - "10.0.0.13" - ], - "host.name": [ - "host01" - ], - "host.name.text": [ - "host01" - ], - "labels.driver_id": [ - "T762465C" - ], - "message": [ - "redis timeout" - ], - "observer.hostname": [ - "dynamic" - ], - "observer.type": [ - "apm-server" - ], - "observer.version": [ - "dynamic" - ], - "parent.id": [ - "333295bfb438ea03" - ], - "processor.event": [ - "error" - ], - "service.language.name": [ - "Go" - ], - "service.language.name.text": [ - "Go" - ], - "service.name": [ - "redis" - ], - "service.name.text": [ - "redis" - ], - "service.node.name": [ - "host01" - ], - "service.node.name.text": [ - "host01" - ], - "timestamp.us": [ - 1576827705006847 - ], - "trace.id": [ - "00000000000000007be2fd98d0973be3" - ] - }, - { - "@timestamp": [ - "2019-12-20T07:41:45.089Z" - ], - "agent.ephemeral_id": [ - "2e3f8db3eb77fae0" - ], - "agent.name": [ - "Jaeger/Go" - ], - "agent.name.text": [ - "Jaeger/Go" - ], - "agent.version": [ - "2.20.1" - ], - "data_stream.dataset": [ - "apm.error" - ], - "data_stream.namespace": [ - "default" - ], - "data_stream.type": [ - "logs" - ], - "error.exception.message": [ - "redis timeout" - ], - "error.grouping_key": [ - "dd09a7d0d9dde0adfcd694967c5a88de" - ], - "error.grouping_name": [ - "redis timeout" - ], - "error.id": [ - "dynamic" - ], - "error.log.message": [ - "redis timeout" - ], - "host.hostname": [ - "host01" - ], - "host.ip": [ - "10.0.0.13" - ], - "host.name": [ - "host01" - ], - "host.name.text": [ - "host01" - ], - "labels.driver_id": [ - "T781861C" - ], - "message": [ - "redis timeout" - ], - "observer.hostname": [ - "dynamic" - ], - "observer.type": [ - "apm-server" - ], - "observer.version": [ - "dynamic" - ], - "parent.id": [ - "614811d6c498bfb0" - ], - "processor.event": [ - "error" - ], - "service.language.name": [ - "Go" - ], - "service.language.name.text": [ - "Go" - ], - "service.name": [ - "redis" - ], - "service.name.text": [ - "redis" - ], - "service.node.name": [ - "host01" - ], - "service.node.name.text": [ - "host01" - ], - "timestamp.us": [ - 1576827705089372 - ], - "trace.id": [ - "00000000000000007be2fd98d0973be3" - ] - }, - { - "@timestamp": [ - "2019-12-20T07:41:45.172Z" - ], - "agent.ephemeral_id": [ - "2e3f8db3eb77fae0" - ], - "agent.name": [ - "Jaeger/Go" - ], - "agent.name.text": [ - "Jaeger/Go" - ], - "agent.version": [ - "2.20.1" - ], - "data_stream.dataset": [ - "apm.error" - ], - "data_stream.namespace": [ - "default" - ], - "data_stream.type": [ - "logs" - ], - "error.exception.message": [ - "redis timeout" - ], - "error.grouping_key": [ - "dd09a7d0d9dde0adfcd694967c5a88de" - ], - "error.grouping_name": [ - "redis timeout" - ], - "error.id": [ - "dynamic" - ], - "error.log.message": [ - "redis timeout" - ], - "host.hostname": [ - "host01" - ], - "host.ip": [ - "10.0.0.13" - ], - "host.name": [ - "host01" - ], - "host.name.text": [ - "host01" - ], - "labels.driver_id": [ - "T752547C" - ], - "message": [ - "redis timeout" - ], - "observer.hostname": [ - "dynamic" - ], - "observer.type": [ - "apm-server" - ], - "observer.version": [ - "dynamic" - ], - "parent.id": [ - "0242ee3774d9eab1" - ], - "processor.event": [ - "error" - ], - "service.language.name": [ - "Go" - ], - "service.language.name.text": [ - "Go" - ], - "service.name": [ - "redis" - ], - "service.name.text": [ - "redis" - ], - "service.node.name": [ - "host01" - ], - "service.node.name.text": [ - "host01" - ], - "timestamp.us": [ - 1576827705172347 - ], - "trace.id": [ - "00000000000000007be2fd98d0973be3" - ] - }, - { - "@timestamp": [ - "2019-12-20T07:41:44.973Z" - ], - "agent.ephemeral_id": [ - "2e3f8db3eb77fae0" - ], - "agent.name": [ - "Jaeger/Go" - ], - "agent.name.text": [ - "Jaeger/Go" - ], - "agent.version": [ - "2.20.1" - ], - "data_stream.dataset": [ - "apm.app.redis" - ], - "data_stream.namespace": [ - "default" - ], - "data_stream.type": [ - "logs" - ], - "event.kind": [ - "event" - ], - "host.hostname": [ - "host01" - ], - "host.ip": [ - "10.0.0.13" - ], - "host.name": [ - "host01" - ], - "host.name.text": [ - "host01" - ], - "labels.level": [ - "info" - ], - "message": [ - "Found drivers" - ], - "observer.hostname": [ - "dynamic" - ], - "observer.type": [ - "apm-server" - ], - "observer.version": [ - "dynamic" - ], - "parent.id": [ - "7be2fd98d0973be3" - ], - "service.language.name": [ - "Go" - ], - "service.language.name.text": [ - "Go" - ], - "service.name": [ - "redis" - ], - "service.name.text": [ - "redis" - ], - "service.node.name": [ - "host01" - ], - "service.node.name.text": [ - "host01" - ], - "span.id": [ - "6e09e8bcefd6b828" - ], - "trace.id": [ - "00000000000000007be2fd98d0973be3" - ] - }, - { - "@timestamp": [ - "2019-12-20T07:41:45.132Z" - ], - "agent.ephemeral_id": [ - "2e3f8db3eb77fae0" - ], - "agent.name": [ - "Jaeger/Go" - ], - "agent.name.text": [ - "Jaeger/Go" - ], - "agent.version": [ - "2.20.1" - ], - "data_stream.dataset": [ - "apm" - ], - "data_stream.namespace": [ - "default" - ], - "data_stream.type": [ - "traces" - ], - "event.outcome": [ - "failure" - ], - "event.success_count": [ - 0 - ], - "host.hostname": [ - "host01" - ], - "host.ip": [ - "10.0.0.13" - ], - "host.name": [ - "host01" - ], - "host.name.text": [ - "host01" - ], - "labels.param_driverID": [ - "T752547C" - ], - "observer.hostname": [ - "dynamic" - ], - "observer.type": [ - "apm-server" - ], - "observer.version": [ - "dynamic" - ], - "parent.id": [ - "7be2fd98d0973be3" - ], - "processor.event": [ - "span" - ], - "service.language.name": [ - "Go" - ], - "service.language.name.text": [ - "Go" - ], - "service.name": [ - "redis" - ], - "service.name.text": [ - "redis" - ], - "service.node.name": [ - "host01" - ], - "service.node.name.text": [ - "host01" - ], - "span.duration.us": [ - 39602 - ], - "span.id": [ - "0242ee3774d9eab1" - ], - "span.name": [ - "GetDriver" - ], - "span.name.text": [ - "GetDriver" - ], - "span.representative_count": [ - 1 - ], - "span.type": [ - "unknown" - ], - "timestamp.us": [ - 1576827705132896 - ], - "trace.id": [ - "00000000000000007be2fd98d0973be3" - ] - }, - { - "@timestamp": [ - "2019-12-20T07:41:45.089Z" - ], - "agent.ephemeral_id": [ - "2e3f8db3eb77fae0" - ], - "agent.name": [ - "Jaeger/Go" - ], - "agent.name.text": [ - "Jaeger/Go" - ], - "agent.version": [ - "2.20.1" - ], - "data_stream.dataset": [ - "apm" - ], - "data_stream.namespace": [ - "default" - ], - "data_stream.type": [ - "traces" - ], - "event.outcome": [ - "success" - ], - "event.success_count": [ - 1 - ], - "host.hostname": [ - "host01" - ], - "host.ip": [ - "10.0.0.13" - ], - "host.name": [ - "host01" - ], - "host.name.text": [ - "host01" - ], - "labels.param_driverID": [ - "T781861C" - ], - "observer.hostname": [ - "dynamic" - ], - "observer.type": [ - "apm-server" - ], - "observer.version": [ - "dynamic" - ], - "parent.id": [ - "7be2fd98d0973be3" - ], - "processor.event": [ - "span" - ], - "service.language.name": [ - "Go" - ], - "service.language.name.text": [ - "Go" - ], - "service.name": [ - "redis" - ], - "service.name.text": [ - "redis" - ], - "service.node.name": [ - "host01" - ], - "service.node.name.text": [ - "host01" - ], - "span.duration.us": [ - 11802 - ], - "span.id": [ - "231604559da84d61" - ], - "span.name": [ - "GetDriver" - ], - "span.name.text": [ - "GetDriver" - ], - "span.representative_count": [ - 1 - ], - "span.type": [ - "unknown" - ], - "timestamp.us": [ - 1576827705089459 - ], - "trace.id": [ - "00000000000000007be2fd98d0973be3" - ] - }, - { - "@timestamp": [ - "2019-12-20T07:41:45.186Z" - ], - "agent.ephemeral_id": [ - "2e3f8db3eb77fae0" - ], - "agent.name": [ - "Jaeger/Go" - ], - "agent.name.text": [ - "Jaeger/Go" - ], - "agent.version": [ - "2.20.1" - ], - "data_stream.dataset": [ - "apm" - ], - "data_stream.namespace": [ - "default" - ], - "data_stream.type": [ - "traces" - ], - "event.outcome": [ - "success" - ], - "event.success_count": [ - 1 - ], - "host.hostname": [ - "host01" - ], - "host.ip": [ - "10.0.0.13" - ], - "host.name": [ - "host01" - ], - "host.name.text": [ - "host01" - ], - "labels.param_driverID": [ - "T757338C" - ], - "observer.hostname": [ - "dynamic" - ], - "observer.type": [ - "apm-server" - ], - "observer.version": [ - "dynamic" - ], - "parent.id": [ - "7be2fd98d0973be3" - ], - "processor.event": [ - "span" - ], - "service.language.name": [ - "Go" - ], - "service.language.name.text": [ - "Go" - ], - "service.name": [ - "redis" - ], - "service.name.text": [ - "redis" - ], - "service.node.name": [ - "host01" - ], - "service.node.name.text": [ - "host01" - ], - "span.duration.us": [ - 10431 - ], - "span.id": [ - "2b4c28f02b272f17" - ], - "span.name": [ - "GetDriver" - ], - "span.name.text": [ - "GetDriver" - ], - "span.representative_count": [ - 1 - ], - "span.type": [ - "unknown" - ], - "timestamp.us": [ - 1576827705186670 - ], - "trace.id": [ - "00000000000000007be2fd98d0973be3" - ] - }, - { - "@timestamp": [ - "2019-12-20T07:41:45.113Z" - ], - "agent.ephemeral_id": [ - "2e3f8db3eb77fae0" - ], - "agent.name": [ - "Jaeger/Go" - ], - "agent.name.text": [ - "Jaeger/Go" - ], - "agent.version": [ - "2.20.1" - ], - "data_stream.dataset": [ - "apm" - ], - "data_stream.namespace": [ - "default" - ], - "data_stream.type": [ - "traces" - ], - "event.outcome": [ - "success" - ], - "event.success_count": [ - 1 - ], - "host.hostname": [ - "host01" - ], - "host.ip": [ - "10.0.0.13" - ], - "host.name": [ - "host01" - ], - "host.name.text": [ - "host01" - ], - "labels.param_driverID": [ - "T708771C" - ], - "observer.hostname": [ - "dynamic" - ], - "observer.type": [ - "apm-server" - ], - "observer.version": [ - "dynamic" - ], - "parent.id": [ - "7be2fd98d0973be3" - ], - "processor.event": [ - "span" - ], - "service.language.name": [ - "Go" - ], - "service.language.name.text": [ - "Go" - ], - "service.name": [ - "redis" - ], - "service.name.text": [ - "redis" - ], - "service.node.name": [ - "host01" - ], - "service.node.name.text": [ - "host01" - ], - "span.duration.us": [ - 11986 - ], - "span.id": [ - "2ef335bad24accc2" - ], - "span.name": [ - "GetDriver" - ], - "span.name.text": [ - "GetDriver" - ], - "span.representative_count": [ - 1 - ], - "span.type": [ - "unknown" - ], - "timestamp.us": [ - 1576827705113531 - ], - "trace.id": [ - "00000000000000007be2fd98d0973be3" - ] - }, - { - "@timestamp": [ - "2019-12-20T07:41:44.973Z" - ], - "agent.ephemeral_id": [ - "2e3f8db3eb77fae0" - ], - "agent.name": [ - "Jaeger/Go" - ], - "agent.name.text": [ - "Jaeger/Go" - ], - "agent.version": [ - "2.20.1" - ], - "data_stream.dataset": [ - "apm" - ], - "data_stream.namespace": [ - "default" - ], - "data_stream.type": [ - "traces" - ], - "event.outcome": [ - "failure" - ], - "event.success_count": [ - 0 - ], - "host.hostname": [ - "host01" - ], - "host.ip": [ - "10.0.0.13" - ], - "host.name": [ - "host01" - ], - "host.name.text": [ - "host01" - ], - "labels.param_driverID": [ - "T762465C" - ], - "observer.hostname": [ - "dynamic" - ], - "observer.type": [ - "apm-server" - ], - "observer.version": [ - "dynamic" - ], - "parent.id": [ - "7be2fd98d0973be3" - ], - "processor.event": [ - "span" - ], - "service.language.name": [ - "Go" - ], - "service.language.name.text": [ - "Go" - ], - "service.name": [ - "redis" - ], - "service.name.text": [ - "redis" - ], - "service.node.name": [ - "host01" - ], - "service.node.name.text": [ - "host01" - ], - "span.duration.us": [ - 33732 - ], - "span.id": [ - "333295bfb438ea03" - ], - "span.name": [ - "GetDriver" - ], - "span.name.text": [ - "GetDriver" - ], - "span.representative_count": [ - 1 - ], - "span.type": [ - "unknown" - ], - "timestamp.us": [ - 1576827704973809 - ], - "trace.id": [ - "00000000000000007be2fd98d0973be3" - ] - }, - { - "@timestamp": [ - "2019-12-20T07:41:45.125Z" - ], - "agent.ephemeral_id": [ - "2e3f8db3eb77fae0" - ], - "agent.name": [ - "Jaeger/Go" - ], - "agent.name.text": [ - "Jaeger/Go" - ], - "agent.version": [ - "2.20.1" - ], - "data_stream.dataset": [ - "apm" - ], - "data_stream.namespace": [ - "default" - ], - "data_stream.type": [ - "traces" - ], - "event.outcome": [ - "success" - ], - "event.success_count": [ - 1 - ], - "host.hostname": [ - "host01" - ], - "host.ip": [ - "10.0.0.13" - ], - "host.name": [ - "host01" - ], - "host.name.text": [ - "host01" - ], - "labels.param_driverID": [ - "T710624C" - ], - "observer.hostname": [ - "dynamic" - ], - "observer.type": [ - "apm-server" - ], - "observer.version": [ - "dynamic" - ], - "parent.id": [ - "7be2fd98d0973be3" - ], - "processor.event": [ - "span" - ], - "service.language.name": [ - "Go" - ], - "service.language.name.text": [ - "Go" - ], - "service.name": [ - "redis" - ], - "service.name.text": [ - "redis" - ], - "service.node.name": [ - "host01" - ], - "service.node.name.text": [ - "host01" - ], - "span.duration.us": [ - 7311 - ], - "span.id": [ - "38ec645e7201224d" - ], - "span.name": [ - "GetDriver" - ], - "span.name.text": [ - "GetDriver" - ], - "span.representative_count": [ - 1 - ], - "span.type": [ - "unknown" - ], - "timestamp.us": [ - 1576827705125567 - ], - "trace.id": [ - "00000000000000007be2fd98d0973be3" - ] - }, - { - "@timestamp": [ - "2019-12-20T07:41:45.054Z" - ], - "agent.ephemeral_id": [ - "2e3f8db3eb77fae0" - ], - "agent.name": [ - "Jaeger/Go" - ], - "agent.name.text": [ - "Jaeger/Go" - ], - "agent.version": [ - "2.20.1" - ], - "data_stream.dataset": [ - "apm" - ], - "data_stream.namespace": [ - "default" - ], - "data_stream.type": [ - "traces" - ], - "event.outcome": [ - "failure" - ], - "event.success_count": [ - 0 - ], - "host.hostname": [ - "host01" - ], - "host.ip": [ - "10.0.0.13" - ], - "host.name": [ - "host01" - ], - "host.name.text": [ - "host01" - ], - "labels.param_driverID": [ - "T781861C" - ], - "observer.hostname": [ - "dynamic" - ], - "observer.type": [ - "apm-server" - ], - "observer.version": [ - "dynamic" - ], - "parent.id": [ - "7be2fd98d0973be3" - ], - "processor.event": [ - "span" - ], - "service.language.name": [ - "Go" - ], - "service.language.name.text": [ - "Go" - ], - "service.name": [ - "redis" - ], - "service.name.text": [ - "redis" - ], - "service.node.name": [ - "host01" - ], - "service.node.name.text": [ - "host01" - ], - "span.duration.us": [ - 35375 - ], - "span.id": [ - "614811d6c498bfb0" - ], - "span.name": [ - "GetDriver" - ], - "span.name.text": [ - "GetDriver" - ], - "span.representative_count": [ - 1 - ], - "span.type": [ - "unknown" - ], - "timestamp.us": [ - 1576827705054046 - ], - "trace.id": [ - "00000000000000007be2fd98d0973be3" - ] - }, - { - "@timestamp": [ - "2019-12-20T07:41:45.101Z" - ], - "agent.ephemeral_id": [ - "2e3f8db3eb77fae0" - ], - "agent.name": [ - "Jaeger/Go" - ], - "agent.name.text": [ - "Jaeger/Go" - ], - "agent.version": [ - "2.20.1" - ], - "data_stream.dataset": [ - "apm" - ], - "data_stream.namespace": [ - "default" - ], - "data_stream.type": [ - "traces" - ], - "event.outcome": [ - "success" - ], - "event.success_count": [ - 1 - ], - "host.hostname": [ - "host01" - ], - "host.ip": [ - "10.0.0.13" - ], - "host.name": [ - "host01" - ], - "host.name.text": [ - "host01" - ], - "labels.param_driverID": [ - "T705860C" - ], - "observer.hostname": [ - "dynamic" - ], - "observer.type": [ - "apm-server" - ], - "observer.version": [ - "dynamic" - ], - "parent.id": [ - "7be2fd98d0973be3" - ], - "processor.event": [ - "span" - ], - "service.language.name": [ - "Go" - ], - "service.language.name.text": [ - "Go" - ], - "service.name": [ - "redis" - ], - "service.name.text": [ - "redis" - ], - "service.node.name": [ - "host01" - ], - "service.node.name.text": [ - "host01" - ], - "span.duration.us": [ - 12236 - ], - "span.id": [ - "61f7ecf24d13c36a" - ], - "span.name": [ - "GetDriver" - ], - "span.name.text": [ - "GetDriver" - ], - "span.representative_count": [ - 1 - ], - "span.type": [ - "unknown" - ], - "timestamp.us": [ - 1576827705101278 - ], - "trace.id": [ - "00000000000000007be2fd98d0973be3" - ] - }, - { - "@timestamp": [ - "2019-12-20T07:41:45.007Z" - ], - "agent.ephemeral_id": [ - "2e3f8db3eb77fae0" - ], - "agent.name": [ - "Jaeger/Go" - ], - "agent.name.text": [ - "Jaeger/Go" - ], - "agent.version": [ - "2.20.1" - ], - "data_stream.dataset": [ - "apm" - ], - "data_stream.namespace": [ - "default" - ], - "data_stream.type": [ - "traces" - ], - "event.outcome": [ - "success" - ], - "event.success_count": [ - 1 - ], - "host.hostname": [ - "host01" - ], - "host.ip": [ - "10.0.0.13" - ], - "host.name": [ - "host01" - ], - "host.name.text": [ - "host01" - ], - "labels.param_driverID": [ - "T762465C" - ], - "observer.hostname": [ - "dynamic" - ], - "observer.type": [ - "apm-server" - ], - "observer.version": [ - "dynamic" - ], - "parent.id": [ - "7be2fd98d0973be3" - ], - "processor.event": [ - "span" - ], - "service.language.name": [ - "Go" - ], - "service.language.name.text": [ - "Go" - ], - "service.name": [ - "redis" - ], - "service.name.text": [ - "redis" - ], - "service.node.name": [ - "host01" - ], - "service.node.name.text": [ - "host01" - ], - "span.duration.us": [ - 9240 - ], - "span.id": [ - "627c37a97e475c2f" - ], - "span.name": [ - "GetDriver" - ], - "span.name.text": [ - "GetDriver" - ], - "span.representative_count": [ - 1 - ], - "span.type": [ - "unknown" - ], - "timestamp.us": [ - 1576827705007578 - ], - "trace.id": [ - "00000000000000007be2fd98d0973be3" - ] - }, - { - "@timestamp": [ - "2019-12-20T07:41:45.172Z" - ], - "agent.ephemeral_id": [ - "2e3f8db3eb77fae0" - ], - "agent.name": [ - "Jaeger/Go" - ], - "agent.name.text": [ - "Jaeger/Go" - ], - "agent.version": [ - "2.20.1" - ], - "data_stream.dataset": [ - "apm" - ], - "data_stream.namespace": [ - "default" - ], - "data_stream.type": [ - "traces" - ], - "event.outcome": [ - "success" - ], - "event.success_count": [ - 1 - ], - "host.hostname": [ - "host01" - ], - "host.ip": [ - "10.0.0.13" - ], - "host.name": [ - "host01" - ], - "host.name.text": [ - "host01" - ], - "labels.param_driverID": [ - "T752547C" - ], - "observer.hostname": [ - "dynamic" - ], - "observer.type": [ - "apm-server" - ], - "observer.version": [ - "dynamic" - ], - "parent.id": [ - "7be2fd98d0973be3" - ], - "processor.event": [ - "span" - ], - "service.language.name": [ - "Go" - ], - "service.language.name.text": [ - "Go" - ], - "service.name": [ - "redis" - ], - "service.name.text": [ - "redis" - ], - "service.node.name": [ - "host01" - ], - "service.node.name.text": [ - "host01" - ], - "span.duration.us": [ - 14029 - ], - "span.id": [ - "6a63d1e81cfc7d95" - ], - "span.name": [ - "GetDriver" - ], - "span.name.text": [ - "GetDriver" - ], - "span.representative_count": [ - 1 - ], - "span.type": [ - "unknown" - ], - "timestamp.us": [ - 1576827705172618 - ], - "trace.id": [ - "00000000000000007be2fd98d0973be3" - ] - }, - { - "@timestamp": [ - "2019-12-20T07:41:45.029Z" - ], - "agent.ephemeral_id": [ - "2e3f8db3eb77fae0" - ], - "agent.name": [ - "Jaeger/Go" - ], - "agent.name.text": [ - "Jaeger/Go" - ], - "agent.version": [ - "2.20.1" - ], - "data_stream.dataset": [ - "apm" - ], - "data_stream.namespace": [ - "default" - ], - "data_stream.type": [ - "traces" - ], - "event.outcome": [ - "success" - ], - "event.success_count": [ - 1 - ], - "host.hostname": [ - "host01" - ], - "host.ip": [ - "10.0.0.13" - ], - "host.name": [ - "host01" - ], - "host.name.text": [ - "host01" - ], - "labels.param_driverID": [ - "T752110C" - ], - "observer.hostname": [ - "dynamic" - ], - "observer.type": [ - "apm-server" - ], - "observer.version": [ - "dynamic" - ], - "parent.id": [ - "7be2fd98d0973be3" - ], - "processor.event": [ - "span" - ], - "service.language.name": [ - "Go" - ], - "service.language.name.text": [ - "Go" - ], - "service.name": [ - "redis" - ], - "service.name.text": [ - "redis" - ], - "service.node.name": [ - "host01" - ], - "service.node.name.text": [ - "host01" - ], - "span.duration.us": [ - 10630 - ], - "span.id": [ - "6b4051dd2a5e2366" - ], - "span.name": [ - "GetDriver" - ], - "span.name.text": [ - "GetDriver" - ], - "span.representative_count": [ - 1 - ], - "span.type": [ - "unknown" - ], - "timestamp.us": [ - 1576827705029415 - ], - "trace.id": [ - "00000000000000007be2fd98d0973be3" - ] - }, - { - "@timestamp": [ - "2019-12-20T07:41:45.040Z" - ], - "agent.ephemeral_id": [ - "2e3f8db3eb77fae0" - ], - "agent.name": [ - "Jaeger/Go" - ], - "agent.name.text": [ - "Jaeger/Go" - ], - "agent.version": [ - "2.20.1" - ], - "data_stream.dataset": [ - "apm" - ], - "data_stream.namespace": [ - "default" - ], - "data_stream.type": [ - "traces" - ], - "event.outcome": [ - "success" - ], - "event.success_count": [ - 1 - ], - "host.hostname": [ - "host01" - ], - "host.ip": [ - "10.0.0.13" - ], - "host.name": [ - "host01" - ], - "host.name.text": [ - "host01" - ], - "labels.param_driverID": [ - "T757670C" - ], - "observer.hostname": [ - "dynamic" - ], - "observer.type": [ - "apm-server" - ], - "observer.version": [ - "dynamic" - ], - "parent.id": [ - "7be2fd98d0973be3" - ], - "processor.event": [ - "span" - ], - "service.language.name": [ - "Go" - ], - "service.language.name.text": [ - "Go" - ], - "service.name": [ - "redis" - ], - "service.name.text": [ - "redis" - ], - "service.node.name": [ - "host01" - ], - "service.node.name.text": [ - "host01" - ], - "span.duration.us": [ - 13946 - ], - "span.id": [ - "6df97a86b9b3451b" - ], - "span.name": [ - "GetDriver" - ], - "span.name.text": [ - "GetDriver" - ], - "span.representative_count": [ - 1 - ], - "span.type": [ - "unknown" - ], - "timestamp.us": [ - 1576827705040082 - ], - "trace.id": [ - "00000000000000007be2fd98d0973be3" - ] - }, - { - "@timestamp": [ - "2019-12-20T07:41:44.954Z" - ], - "agent.ephemeral_id": [ - "2e3f8db3eb77fae0" - ], - "agent.name": [ - "Jaeger/Go" - ], - "agent.name.text": [ - "Jaeger/Go" - ], - "agent.version": [ - "2.20.1" - ], - "data_stream.dataset": [ - "apm" - ], - "data_stream.namespace": [ - "default" - ], - "data_stream.type": [ - "traces" - ], - "event.outcome": [ - "success" - ], - "event.success_count": [ - 1 - ], - "host.hostname": [ - "host01" - ], - "host.ip": [ - "10.0.0.13" - ], - "host.name": [ - "host01" - ], - "host.name.text": [ - "host01" - ], - "labels.param_location": [ - "728,326" - ], - "observer.hostname": [ - "dynamic" - ], - "observer.type": [ - "apm-server" - ], - "observer.version": [ - "dynamic" - ], - "parent.id": [ - "7be2fd98d0973be3" - ], - "processor.event": [ - "span" - ], - "service.language.name": [ - "Go" - ], - "service.language.name.text": [ - "Go" - ], - "service.name": [ - "redis" - ], - "service.name.text": [ - "redis" - ], - "service.node.name": [ - "host01" - ], - "service.node.name.text": [ - "host01" - ], - "span.duration.us": [ - 19711 - ], - "span.id": [ - "6e09e8bcefd6b828" - ], - "span.name": [ - "FindDriverIDs" - ], - "span.name.text": [ - "FindDriverIDs" - ], - "span.representative_count": [ - 1 - ], - "span.type": [ - "unknown" - ], - "timestamp.us": [ - 1576827704954062 - ], - "trace.id": [ - "00000000000000007be2fd98d0973be3" - ] - }, - { - "@timestamp": [ - "2019-12-20T07:41:45.016Z" - ], - "agent.ephemeral_id": [ - "2e3f8db3eb77fae0" - ], - "agent.name": [ - "Jaeger/Go" - ], - "agent.name.text": [ - "Jaeger/Go" - ], - "agent.version": [ - "2.20.1" - ], - "data_stream.dataset": [ - "apm" - ], - "data_stream.namespace": [ - "default" - ], - "data_stream.type": [ - "traces" - ], - "event.outcome": [ - "success" - ], - "event.success_count": [ - 1 - ], - "host.hostname": [ - "host01" - ], - "host.ip": [ - "10.0.0.13" - ], - "host.name": [ - "host01" - ], - "host.name.text": [ - "host01" - ], - "labels.param_driverID": [ - "T712515C" - ], - "observer.hostname": [ - "dynamic" - ], - "observer.type": [ - "apm-server" - ], - "observer.version": [ - "dynamic" - ], - "parent.id": [ - "7be2fd98d0973be3" - ], - "processor.event": [ - "span" - ], - "service.language.name": [ - "Go" - ], - "service.language.name.text": [ - "Go" - ], - "service.name": [ - "redis" - ], - "service.name.text": [ - "redis" - ], - "service.node.name": [ - "host01" - ], - "service.node.name.text": [ - "host01" - ], - "span.duration.us": [ - 12561 - ], - "span.id": [ - "7bd7663d39c5a847" - ], - "span.name": [ - "GetDriver" - ], - "span.name.text": [ - "GetDriver" - ], - "span.representative_count": [ - 1 - ], - "span.type": [ - "unknown" - ], - "timestamp.us": [ - 1576827705016845 - ], - "trace.id": [ - "00000000000000007be2fd98d0973be3" - ] - } -] diff --git a/systemtest/approvals/TestOTLPGRPCLogsClientIP.approved.json b/systemtest/approvals/TestOTLPGRPCLogsClientIP.approved.json index b7294fb9d0e..1ba5a3208e6 100644 --- a/systemtest/approvals/TestOTLPGRPCLogsClientIP.approved.json +++ b/systemtest/approvals/TestOTLPGRPCLogsClientIP.approved.json @@ -12,6 +12,9 @@ "agent.version": [ "unknown" ], + "client.geo.city_name": [ + "dynamic" + ], "client.geo.continent_name": [ "Europe" ], @@ -24,6 +27,12 @@ "client.geo.location": [ "dynamic" ], + "client.geo.region_iso_code": [ + "dynamic" + ], + "client.geo.region_name": [ + "dynamic" + ], "client.ip": [ "89.160.20.128" ], diff --git a/systemtest/approvals/TestOTLPGRPCTraces.approved.json b/systemtest/approvals/TestOTLPGRPCTraces.approved.json index cbff9278129..b7db09fcb01 100644 --- a/systemtest/approvals/TestOTLPGRPCTraces.approved.json +++ b/systemtest/approvals/TestOTLPGRPCTraces.approved.json @@ -31,7 +31,7 @@ "*errors.errorString" ], "error.grouping_key": [ - "14f4d08792a45fce53a46c93851e36e1" + "7f440eedb20ba958" ], "error.grouping_name": [ "kablamo" diff --git a/systemtest/approvals/TestRUMErrorSourcemapping/absolute_bundle_filepath/standalone.approved.json b/systemtest/approvals/TestRUMErrorSourcemapping/absolute_bundle_filepath/standalone.approved.json index 1652cdaada6..ebd68d66bc3 100644 --- a/systemtest/approvals/TestRUMErrorSourcemapping/absolute_bundle_filepath/standalone.approved.json +++ b/systemtest/approvals/TestRUMErrorSourcemapping/absolute_bundle_filepath/standalone.approved.json @@ -34,7 +34,7 @@ "Error" ], "error.grouping_key": [ - "89e23da755c2dd759d2d529e37c92b8f" + "9b83ced5381eaafe" ], "error.grouping_name": [ "Uncaught Error: log timeout test error" @@ -42,6 +42,9 @@ "error.id": [ "aba2688e033848ce9c4e4005f1caa534" ], + "error.log.level": [ + "error" + ], "error.log.message": [ "Uncaught Error: log timeout test error" ], diff --git a/systemtest/approvals/TestRUMErrorSourcemapping/relative_bundle_filepath/standalone.approved.json b/systemtest/approvals/TestRUMErrorSourcemapping/relative_bundle_filepath/standalone.approved.json index 1652cdaada6..ebd68d66bc3 100644 --- a/systemtest/approvals/TestRUMErrorSourcemapping/relative_bundle_filepath/standalone.approved.json +++ b/systemtest/approvals/TestRUMErrorSourcemapping/relative_bundle_filepath/standalone.approved.json @@ -34,7 +34,7 @@ "Error" ], "error.grouping_key": [ - "89e23da755c2dd759d2d529e37c92b8f" + "9b83ced5381eaafe" ], "error.grouping_name": [ "Uncaught Error: log timeout test error" @@ -42,6 +42,9 @@ "error.id": [ "aba2688e033848ce9c4e4005f1caa534" ], + "error.log.level": [ + "error" + ], "error.log.message": [ "Uncaught Error: log timeout test error" ], diff --git a/systemtest/approvals/TestRUMXForwardedFor.approved.json b/systemtest/approvals/TestRUMXForwardedFor.approved.json index 89d28519fa6..f1b96a8c854 100644 --- a/systemtest/approvals/TestRUMXForwardedFor.approved.json +++ b/systemtest/approvals/TestRUMXForwardedFor.approved.json @@ -13,7 +13,7 @@ "5.5.0" ], "client.geo.city_name": [ - "Perth" + "dynamic" ], "client.geo.continent_name": [ "Oceania" @@ -28,10 +28,10 @@ "dynamic" ], "client.geo.region_iso_code": [ - "AU-WA" + "dynamic" ], "client.geo.region_name": [ - "Western Australia" + "dynamic" ], "client.ip": [ "220.244.41.16" @@ -132,7 +132,7 @@ "5.5.0" ], "client.geo.city_name": [ - "Perth" + "dynamic" ], "client.geo.continent_name": [ "Oceania" @@ -147,10 +147,10 @@ "dynamic" ], "client.geo.region_iso_code": [ - "AU-WA" + "dynamic" ], "client.geo.region_name": [ - "Western Australia" + "dynamic" ], "client.ip": [ "220.244.41.16" diff --git a/systemtest/auth_test.go b/systemtest/auth_test.go index 3e6c68b3811..bd0000f5ddf 100644 --- a/systemtest/auth_test.go +++ b/systemtest/auth_test.go @@ -54,10 +54,10 @@ func TestAuth(t *testing.T) { err := srv.Start() require.NoError(t, err) - apiKey := createAPIKey(t, t.Name()+":all") - apiKeySourcemap := createAPIKey(t, t.Name()+":sourcemap", "--sourcemap") - apiKeyIngest := createAPIKey(t, t.Name()+":ingest", "--ingest") - apiKeyAgentConfig := createAPIKey(t, t.Name()+":agentconfig", "--agent-config") + apiKey := systemtest.CreateAPIKey(t, t.Name()+":all", []string{"config_agent:read", "sourcemap:write", "event:write"}) + apiKeySourcemap := systemtest.CreateAPIKey(t, t.Name()+":sourcemap", []string{"sourcemap:write"}) + apiKeyIngest := systemtest.CreateAPIKey(t, t.Name()+":ingest", []string{"event:write"}) + apiKeyAgentConfig := systemtest.CreateAPIKey(t, t.Name()+":agentconfig", []string{"config_agent:read"}) runWithMethods := func(t *testing.T, name string, f func(t *testing.T, apiKey string, headers http.Header)) { t.Run(name, func(t *testing.T) { @@ -189,12 +189,3 @@ func copyHeaders(to, from http.Header) { } } } - -func createAPIKey(t *testing.T, name string, args ...string) string { - args = append([]string{"--name", name, "--json"}, args...) - cmd := apiKeyCommand("create", args...) - out, err := cmd.CombinedOutput() - require.NoError(t, err) - attrs := decodeJSONMap(t, bytes.NewReader(out)) - return attrs["credentials"].(string) -} diff --git a/systemtest/benchtest/expvar/expvar.go b/systemtest/benchtest/expvar/expvar.go index 452e3ddf0bf..65d897bf555 100644 --- a/systemtest/benchtest/expvar/expvar.go +++ b/systemtest/benchtest/expvar/expvar.go @@ -36,6 +36,7 @@ type expvar struct { LibbeatStats ElasticResponseStats OTLPResponseStats + TailSamplingStats // UncompressedBytes holds the number of bytes of uncompressed // data that the server has read from the Elastic APM events @@ -50,12 +51,15 @@ type expvar struct { } type ElasticResponseStats struct { - TotalElasticResponses int64 `json:"apm-server.server.response.count"` - ErrorElasticResponses int64 `json:"apm-server.server.response.errors.count"` - TransactionsProcessed int64 `json:"apm-server.processor.transaction.transformations"` - SpansProcessed int64 `json:"apm-server.processor.span.transformations"` - MetricsProcessed int64 `json:"apm-server.processor.metric.transformations"` - ErrorsProcessed int64 `json:"apm-server.processor.error.transformations"` + TotalElasticResponses int64 `json:"apm-server.server.response.count"` + ErrorElasticResponses int64 `json:"apm-server.server.response.errors.count"` + TransactionsProcessed int64 `json:"apm-server.processor.transaction.transformations"` + SpansProcessed int64 `json:"apm-server.processor.span.transformations"` + MetricsProcessed int64 `json:"apm-server.processor.metric.transformations"` + ErrorsProcessed int64 `json:"apm-server.processor.error.transformations"` + IntakeEventsAccepted int64 `json:"apm-server.processor.stream.accepted"` + IntakeEventsErrorsInvalid int64 `json:"apm-server.processor.stream.errors.invalid"` + IntakeEventsErrorsTooLarge int64 `json:"apm-server.processor.stream.errors.toolarge"` } type OTLPResponseStats struct { @@ -72,6 +76,11 @@ type LibbeatStats struct { RSSMemoryBytes int64 `json:"beat.memstats.rss"` } +type TailSamplingStats struct { + TBSLsmSize int64 `json:"apm-server.sampling.tail.storage.lsm_size"` + TBSVlogSize int64 `json:"apm-server.sampling.tail.storage.value_log_size"` +} + func queryExpvar(ctx context.Context, out *expvar, srv string) error { req, err := http.NewRequest("GET", srv+"/debug/vars", nil) if err != nil { @@ -113,6 +122,7 @@ func queryExpvar(ctx context.Context, out *expvar, srv string) error { aggregateResponseStats(s.ElasticResponseStats, &result.ElasticResponseStats) aggregateOTLPResponseStats(s.OTLPResponseStats, &result.OTLPResponseStats) aggregateLibbeatStats(s.LibbeatStats, &result.LibbeatStats) + aggregateTailSamplingStats(s.TailSamplingStats, &result.TailSamplingStats) result.UncompressedBytes += s.UncompressedBytes result.AvailableBulkRequests += s.AvailableBulkRequests } @@ -197,6 +207,9 @@ func aggregateResponseStats(from ElasticResponseStats, to *ElasticResponseStats) to.SpansProcessed += from.SpansProcessed to.TransactionsProcessed += from.TransactionsProcessed to.TotalElasticResponses += from.TotalElasticResponses + to.IntakeEventsAccepted += from.IntakeEventsAccepted + to.IntakeEventsErrorsInvalid += from.IntakeEventsErrorsInvalid + to.IntakeEventsErrorsTooLarge += from.IntakeEventsErrorsTooLarge } func aggregateOTLPResponseStats(from OTLPResponseStats, to *OTLPResponseStats) { @@ -205,3 +218,8 @@ func aggregateOTLPResponseStats(from OTLPResponseStats, to *OTLPResponseStats) { to.ErrorOTLPTracesResponses += from.ErrorOTLPTracesResponses to.ErrorOTLPMetricsResponses += from.ErrorOTLPMetricsResponses } + +func aggregateTailSamplingStats(from TailSamplingStats, to *TailSamplingStats) { + to.TBSLsmSize += from.TBSLsmSize + to.TBSVlogSize += from.TBSVlogSize +} diff --git a/systemtest/benchtest/expvar/metrics.go b/systemtest/benchtest/expvar/metrics.go index 328c78bd9a5..4bff808ce40 100644 --- a/systemtest/benchtest/expvar/metrics.go +++ b/systemtest/benchtest/expvar/metrics.go @@ -34,6 +34,9 @@ const ( MemBytes ActiveEvents TotalEvents + IntakeEventsAccepted + IntakeEventsErrorsInvalid + IntakeEventsErrorsTooLarge TransactionsProcessed SpansProcessed MetricsProcessed @@ -47,6 +50,8 @@ const ( ErrorElasticResponses ErrorOTLPTracesResponses ErrorOTLPMetricsResponses + TBSLsmSize + TBSVlogSize ) type AggregateStats struct { @@ -152,6 +157,9 @@ func (c *Collector) accumulate(e expvar) { c.processMetric(ActiveEvents, e.ActiveEvents) c.processMetric(RSSMemoryBytes, e.RSSMemoryBytes) c.processMetric(AvailableBulkRequests, e.AvailableBulkRequests) + c.processMetric(IntakeEventsAccepted, e.IntakeEventsAccepted) + c.processMetric(IntakeEventsErrorsInvalid, e.IntakeEventsErrorsInvalid) + c.processMetric(IntakeEventsErrorsTooLarge, e.IntakeEventsErrorsTooLarge) c.processMetric(TransactionsProcessed, e.TransactionsProcessed) c.processMetric(SpansProcessed, e.SpansProcessed) c.processMetric(MetricsProcessed, e.MetricsProcessed) @@ -164,6 +172,8 @@ func (c *Collector) accumulate(e expvar) { c.processMetric(MemBytes, int64(e.TotalAlloc)) c.processMetric(HeapAlloc, int64(e.HeapAlloc)) c.processMetric(HeapObjects, int64(e.HeapObjects)) + c.processMetric(TBSLsmSize, e.TBSLsmSize) + c.processMetric(TBSVlogSize, e.TBSVlogSize) } func (c *Collector) processMetric(m Metric, val int64) { diff --git a/systemtest/benchtest/main.go b/systemtest/benchtest/main.go index 5422915b491..ee3800bd650 100644 --- a/systemtest/benchtest/main.go +++ b/systemtest/benchtest/main.go @@ -112,6 +112,8 @@ func addExpvarMetrics(result *testing.BenchmarkResult, collector *expvar.Collect result.MemBytes = uint64(collector.Delta(expvar.MemBytes)) result.Extra["events/sec"] = float64(collector.Delta(expvar.TotalEvents)) / result.T.Seconds() if detailed { + result.Extra["intake_events_accepted/sec"] = float64(collector.Delta(expvar.IntakeEventsAccepted)) / result.T.Seconds() + result.Extra["intake_events_errors/sec"] = float64(collector.Delta(expvar.IntakeEventsErrorsInvalid)+collector.Delta(expvar.IntakeEventsErrorsTooLarge)) / result.T.Seconds() result.Extra["txs/sec"] = float64(collector.Delta(expvar.TransactionsProcessed)) / result.T.Seconds() result.Extra["spans/sec"] = float64(collector.Delta(expvar.SpansProcessed)) / result.T.Seconds() result.Extra["metrics/sec"] = float64(collector.Delta(expvar.MetricsProcessed)) / result.T.Seconds() @@ -122,6 +124,8 @@ func addExpvarMetrics(result *testing.BenchmarkResult, collector *expvar.Collect result.Extra["max_heap_alloc"] = float64(collector.Get(expvar.HeapAlloc).Max) result.Extra["max_heap_objects"] = float64(collector.Get(expvar.HeapObjects).Max) result.Extra["mean_available_indexers"] = float64(collector.Get(expvar.AvailableBulkRequests).Mean) + result.Extra["tbs_lsm_size"] = float64(collector.Get(expvar.TBSLsmSize).Max) + result.Extra["tbs_vlog_size"] = float64(collector.Get(expvar.TBSVlogSize).Max) } // Record the number of error responses returned by the server: lower is better. diff --git a/systemtest/benchtest/main_test.go b/systemtest/benchtest/main_test.go index 14a7bbd64b9..a06914e66c7 100644 --- a/systemtest/benchtest/main_test.go +++ b/systemtest/benchtest/main_test.go @@ -137,10 +137,15 @@ func TestAddExpvarMetrics(t *testing.T) { detailed: true, responseMetrics: []string{ `"libbeat.output.events.total": 24`, + `"apm-server.processor.stream.accepted": 111`, + `"apm-server.processor.stream.errors.invalid": 200`, + `"apm-server.processor.stream.errors.toolarge": 300`, `"apm-server.processor.transaction.transformations": 7`, `"apm-server.processor.span.transformations": 5`, `"apm-server.processor.metric.transformations": 9`, `"apm-server.processor.error.transformations": 3`, + `"apm-server.sampling.tail.storage.lsm_size": 10`, + `"apm-server.sampling.tail.storage.value_log_size": 11`, `"beat.runtime.goroutines": 4`, `"beat.memstats.rss": 1048576`, `"output.elasticsearch.bulk_requests.available": 0`, @@ -153,18 +158,22 @@ func TestAddExpvarMetrics(t *testing.T) { `"HeapObjects": 102`, }, expectedResult: map[string]float64{ - "events/sec": 24, - "txs/sec": 7, - "spans/sec": 5, - "metrics/sec": 9, - "errors/sec": 3, - "gc_cycles": 10, - "max_rss": 1048576, - "max_goroutines": 4, - "max_heap_alloc": 10240, - "max_heap_objects": 102, - "mean_available_indexers": 0, - "error_responses/sec": 1, + "events/sec": 24, + "intake_events_accepted/sec": 111, + "intake_events_errors/sec": 500, + "txs/sec": 7, + "spans/sec": 5, + "metrics/sec": 9, + "errors/sec": 3, + "gc_cycles": 10, + "max_rss": 1048576, + "max_goroutines": 4, + "max_heap_alloc": 10240, + "max_heap_objects": 102, + "mean_available_indexers": 0, + "error_responses/sec": 1, + "tbs_lsm_size": 10, + "tbs_vlog_size": 11, }, }, } diff --git a/systemtest/cmdflags_test.go b/systemtest/cmdflags_test.go index a8b416e8f5a..3d9e289a627 100644 --- a/systemtest/cmdflags_test.go +++ b/systemtest/cmdflags_test.go @@ -24,7 +24,7 @@ import ( ) func TestAPMServerEnvironment(t *testing.T) { - // Check that apm-server starts up cleanly with the "-environment" flag. + // Check that apm-server starts up cleanly with the "--environment" flag. for _, env := range []string{ "container", "systemd", @@ -35,7 +35,7 @@ func TestAPMServerEnvironment(t *testing.T) { t.Run(env, func(t *testing.T) { t.Parallel() // NewServer adds a cleanup to close the server. - apmservertest.NewServerTB(t, "-environment", env) + apmservertest.NewServerTB(t, "--environment", env) }) } } diff --git a/systemtest/containers.go b/systemtest/containers.go index 697ca431eb1..fd231687560 100644 --- a/systemtest/containers.go +++ b/systemtest/containers.go @@ -54,7 +54,7 @@ var ( systemtestDir string ) -func init() { +func initContainers() { _, filename, _, ok := runtime.Caller(0) if !ok { panic("could not locate systemtest directory") diff --git a/systemtest/elasticsearch.go b/systemtest/elasticsearch.go index 0a861755308..e259bb4b6f0 100644 --- a/systemtest/elasticsearch.go +++ b/systemtest/elasticsearch.go @@ -19,6 +19,8 @@ package systemtest import ( "context" + "encoding/json" + "io" "net/url" "testing" "time" @@ -44,7 +46,7 @@ var ( Elasticsearch *espoll.Client ) -func init() { +func initElasticSearch() { cfg := newElasticsearchConfig() cfg.Username = adminElasticsearchUser cfg.Password = adminElasticsearchPass @@ -55,18 +57,6 @@ func init() { Elasticsearch = &espoll.Client{Client: client} } -// NewElasticsearchClientWithAPIKey returns a new espoll.Client, -// configured to use apiKey for authentication. -func NewElasticsearchClientWithAPIKey(apiKey string) *espoll.Client { - cfg := newElasticsearchConfig() - cfg.APIKey = apiKey - client, err := elasticsearch.NewClient(cfg) - if err != nil { - panic(err) - } - return &espoll.Client{Client: client} -} - func newElasticsearchConfig() elasticsearch.Config { var addresses []string for _, host := range apmservertest.DefaultConfig().Output.Elasticsearch.Hosts { @@ -115,22 +105,49 @@ func ChangeUserPassword(t testing.TB, username, password string) { } } -// InvalidateAPIKeys invalidates all API Keys for the apm-server user. -func InvalidateAPIKeys(t testing.TB) { - req := esapi.SecurityInvalidateAPIKeyRequest{ - Body: esutil.NewJSONReader(map[string]interface{}{ - "username": apmservertest.DefaultConfig().Output.Elasticsearch.Username, +func CreateAPIKey(t testing.TB, name string, privileges []string) string { + req := esapi.SecurityCreateAPIKeyRequest{ + Body: esutil.NewJSONReader(map[string]any{ + "name": name, + "role_descriptors": map[string]any{ + "apm": map[string]any{ + "applications": []map[string]any{ + { + "application": "apm", + "privileges": privileges, + "resources": []string{"*"}, + }, + }, + }, + }, + "metadata": map[string]any{"application": "apm"}, }), } - if _, err := Elasticsearch.Do(context.Background(), req, nil); err != nil { + + res, err := Elasticsearch.Do(context.Background(), req, nil) + if err != nil { + t.Fatal(err) + } + + b, err := io.ReadAll(res.Body) + if err != nil { + t.Fatal(err) + } + + m := make(map[string]any) + if err := json.Unmarshal(b, &m); err != nil { t.Fatal(err) } + + return m["encoded"].(string) } -// InvalidateAPIKey invalidates the API Key with the given ID. -func InvalidateAPIKey(t testing.TB, id string) { +// InvalidateAPIKeys invalidates all API Keys for the apm-server user. +func InvalidateAPIKeys(t testing.TB) { req := esapi.SecurityInvalidateAPIKeyRequest{ - Body: esutil.NewJSONReader(map[string]interface{}{"id": id}), + Body: esutil.NewJSONReader(map[string]interface{}{ + "username": apmservertest.DefaultConfig().Output.Elasticsearch.Username, + }), } if _, err := Elasticsearch.Do(context.Background(), req, nil); err != nil { t.Fatal(err) diff --git a/systemtest/go.mod b/systemtest/go.mod index b2307b7a631..c5bd71dd57c 100644 --- a/systemtest/go.mod +++ b/systemtest/go.mod @@ -3,38 +3,37 @@ module github.com/elastic/apm-server/systemtest go 1.23.0 require ( - github.com/docker/docker v27.3.1+incompatible + github.com/docker/docker v27.5.1+incompatible github.com/docker/go-connections v0.5.0 github.com/elastic/apm-perf v0.0.0-20230608162138-29920c01cfd6 github.com/elastic/apm-tools v0.0.0-20240607105915-a4f490dc6959 - github.com/elastic/go-elasticsearch/v8 v8.15.0 + github.com/elastic/go-elasticsearch/v8 v8.17.0 github.com/elastic/go-lumber v0.1.1 - github.com/elastic/go-sysinfo v1.11.1 + github.com/elastic/go-sysinfo v1.15.0 github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 github.com/hashicorp/go-multierror v1.1.1 - github.com/jaegertracing/jaeger v1.62.0 - github.com/stretchr/testify v1.9.0 - github.com/testcontainers/testcontainers-go v0.33.0 + github.com/stretchr/testify v1.10.0 + github.com/testcontainers/testcontainers-go v0.35.0 github.com/tidwall/gjson v1.18.0 - go.elastic.co/apm/v2 v2.6.2 + go.elastic.co/apm/v2 v2.6.3 go.elastic.co/fastjson v1.4.0 - go.opentelemetry.io/collector/pdata v1.17.0 - go.opentelemetry.io/collector/semconv v0.111.0 - go.opentelemetry.io/otel v1.30.0 - go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.30.0 - go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.30.0 - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.30.0 - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.30.0 - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.30.0 - go.opentelemetry.io/otel/metric v1.30.0 - go.opentelemetry.io/otel/sdk v1.30.0 - go.opentelemetry.io/otel/sdk/metric v1.30.0 - go.opentelemetry.io/otel/trace v1.30.0 + go.opentelemetry.io/collector/pdata v1.24.0 + go.opentelemetry.io/collector/semconv v0.118.0 + go.opentelemetry.io/otel v1.34.0 + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.34.0 + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.34.0 + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0 + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0 + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.34.0 + go.opentelemetry.io/otel/metric v1.34.0 + go.opentelemetry.io/otel/sdk v1.34.0 + go.opentelemetry.io/otel/sdk/metric v1.34.0 + go.opentelemetry.io/otel/trace v1.34.0 go.uber.org/zap v1.27.0 - golang.org/x/sync v0.8.0 - golang.org/x/sys v0.26.0 - golang.org/x/time v0.7.0 - google.golang.org/grpc v1.67.1 + golang.org/x/sync v0.10.0 + golang.org/x/sys v0.29.0 + golang.org/x/time v0.9.0 + google.golang.org/grpc v1.70.0 gopkg.in/yaml.v3 v3.0.1 ) @@ -47,7 +46,7 @@ require ( github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/containerd/log v0.1.0 // indirect github.com/containerd/platforms v0.2.1 // indirect - github.com/cpuguy83/dockercfg v0.3.1 // indirect + github.com/cpuguy83/dockercfg v0.3.2 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/distribution/reference v0.6.0 // indirect github.com/docker/go-units v0.5.0 // indirect @@ -57,15 +56,13 @@ require ( github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-ole/go-ole v1.2.6 // indirect - github.com/gogo/googleapis v1.4.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/google/go-cmp v0.6.0 // indirect github.com/google/uuid v1.6.0 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.25.1 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect - github.com/joeshaw/multierror v0.0.0-20140124173710-69b34d4ec901 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/klauspost/compress v1.17.10 // indirect + github.com/klauspost/compress v1.17.11 // indirect github.com/lufia/plan9stats v0.0.0-20220913051719-115f729f3c8c // indirect github.com/magiconair/properties v1.8.7 // indirect github.com/moby/docker-image-spec v1.3.1 // indirect @@ -92,14 +89,15 @@ require ( github.com/tklauser/go-sysconf v0.3.12 // indirect github.com/tklauser/numcpus v0.6.1 // indirect github.com/yusufpapurcu/wmi v1.2.4 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.55.0 // indirect - go.opentelemetry.io/proto/otlp v1.3.1 // indirect + go.opentelemetry.io/auto/sdk v1.1.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.56.0 // indirect + go.opentelemetry.io/proto/otlp v1.5.0 // indirect go.uber.org/multierr v1.11.0 // indirect - golang.org/x/crypto v0.28.0 // indirect - golang.org/x/net v0.30.0 // indirect - golang.org/x/text v0.19.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 // indirect - google.golang.org/protobuf v1.34.2 // indirect + golang.org/x/crypto v0.32.0 // indirect + golang.org/x/net v0.34.0 // indirect + golang.org/x/text v0.21.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20250115164207-1a7da9e5054f // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f // indirect + google.golang.org/protobuf v1.36.3 // indirect howett.net/plist v1.0.0 // indirect ) diff --git a/systemtest/go.sum b/systemtest/go.sum index f0817660e3d..37e267f1aa3 100644 --- a/systemtest/go.sum +++ b/systemtest/go.sum @@ -17,8 +17,8 @@ github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= github.com/containerd/platforms v0.2.1 h1:zvwtM3rz2YHPQsF2CHYM8+KtB5dvhISiXh5ZpSBQv6A= github.com/containerd/platforms v0.2.1/go.mod h1:XHCb+2/hzowdiut9rkudds9bE5yJ7npe7dG/wG+uFPw= -github.com/cpuguy83/dockercfg v0.3.1 h1:/FpZ+JaygUR/lZP2NlFI2DVfrOEMAIKP5wWEJdoYe9E= -github.com/cpuguy83/dockercfg v0.3.1/go.mod h1:sugsbF4//dDlL/i+S+rtpIWp+5h0BHJHfjj5/jFyUJc= +github.com/cpuguy83/dockercfg v0.3.2 h1:DlJTyZGBDlXqUZ2Dk2Q3xHs/FtnooJJVaad2S9GKorA= +github.com/cpuguy83/dockercfg v0.3.2/go.mod h1:sugsbF4//dDlL/i+S+rtpIWp+5h0BHJHfjj5/jFyUJc= github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -27,8 +27,8 @@ github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1 github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= -github.com/docker/docker v27.3.1+incompatible h1:KttF0XoteNTicmUtBO0L2tP+J7FGRFTjaEF4k6WdhfI= -github.com/docker/docker v27.3.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v27.5.1+incompatible h1:4PYU5dnBYqRQi0294d1FBECqT9ECWeQAIfE8q4YnPY8= +github.com/docker/docker v27.5.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c= github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= @@ -39,12 +39,12 @@ github.com/elastic/apm-tools v0.0.0-20240607105915-a4f490dc6959 h1:N76IIqinReb57 github.com/elastic/apm-tools v0.0.0-20240607105915-a4f490dc6959/go.mod h1:kHvCTEbLhFbP0g2k4R8BMLIANRWzqHA7e84AQ84TQLc= github.com/elastic/elastic-transport-go/v8 v8.6.0 h1:Y2S/FBjx1LlCv5m6pWAF2kDJAHoSjSRSJCApolgfthA= github.com/elastic/elastic-transport-go/v8 v8.6.0/go.mod h1:YLHer5cj0csTzNFXoNQ8qhtGY1GTvSqPnKWKaqQE3Hk= -github.com/elastic/go-elasticsearch/v8 v8.15.0 h1:IZyJhe7t7WI3NEFdcHnf6IJXqpRf+8S8QWLtZYYyBYk= -github.com/elastic/go-elasticsearch/v8 v8.15.0/go.mod h1:HCON3zj4btpqs2N1jjsAy4a/fiAul+YBP00mBH4xik8= +github.com/elastic/go-elasticsearch/v8 v8.17.0 h1:e9cWksE/Fr7urDRmGPGp47Nsp4/mvNOrU8As1l2HQQ0= +github.com/elastic/go-elasticsearch/v8 v8.17.0/go.mod h1:lGMlgKIbYoRvay3xWBeKahAiJOgmFDsjZC39nmO3H64= github.com/elastic/go-lumber v0.1.1 h1:aae5rSBnwBvdB0aShJ7AbOYPyvP1/wS/JIOC1A4D1DM= github.com/elastic/go-lumber v0.1.1/go.mod h1:DMVoFv7YM71enE9X5vWJWWv7wvQNtzXh7bPeKukDccY= -github.com/elastic/go-sysinfo v1.11.1 h1:g9mwl05njS4r69TisC+vwHWTSKywZFYYUu3so3T/Lao= -github.com/elastic/go-sysinfo v1.11.1/go.mod h1:6KQb31j0QeWBDF88jIdWSxE8cwoOB9tO4Y4osN7Q70E= +github.com/elastic/go-sysinfo v1.15.0 h1:54pRFlAYUlVNQ2HbXzLVZlV+fxS7Eax49stzg95M4Xw= +github.com/elastic/go-sysinfo v1.15.0/go.mod h1:jPSuTgXG+dhhh0GKIyI2Cso+w5lPJ5PvVqKlL8LV/Hk= github.com/elastic/go-windows v1.0.1 h1:AlYZOldA+UJ0/2nBuqWdo90GFCgG9xuyw9SYzGUtJm0= github.com/elastic/go-windows v1.0.1/go.mod h1:FoVvqWSun28vaDQPbj2Elfc0JahhPB7WQEGa3c814Ss= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= @@ -56,10 +56,10 @@ github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= -github.com/gogo/googleapis v1.4.1 h1:1Yx4Myt7BxzvUr5ldGSbwYiZG6t9wGBZ+8/fX3Wvtq0= -github.com/gogo/googleapis v1.4.1/go.mod h1:2lpHqI5OcWCtVElxXnPt+s8oJvMpySlOyM6xDCrzib4= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= @@ -69,26 +69,22 @@ github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJY github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 h1:asbCHRVmodnJTuQ3qamDwqVOIjwqUPTYmYuemVOx+Ys= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0/go.mod h1:ggCgvZ2r7uOoQjOyu2Y1NhHmEPPzzuhWgcza5M1Ji1I= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.25.1 h1:VNqngBF40hVlDloBruUehVYC3ArSgIyScOAyMRqBxRg= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.25.1/go.mod h1:RBRO7fro65R6tjKzYgLAFo0t1QEXY1Dp+i/bvpRiqiQ= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/jaegertracing/jaeger v1.62.0 h1:YoaJ2e8oVz5sqGGlVAKSUCED8DzJ1q7PojBmZFNKoJA= -github.com/jaegertracing/jaeger v1.62.0/go.mod h1:jhEIHazwyb+a6xlRBi+p96BAvTYTSmGkghcwdQfV7FM= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= -github.com/joeshaw/multierror v0.0.0-20140124173710-69b34d4ec901 h1:rp+c0RAYOWj8l6qbCUTSiRLG/iKnW3K3/QfPPuSsBt4= -github.com/joeshaw/multierror v0.0.0-20140124173710-69b34d4ec901/go.mod h1:Z86h9688Y0wesXCyonoVr47MasHilkuLMqGhRZ4Hpak= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.11.2/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= -github.com/klauspost/compress v1.17.10 h1:oXAz+Vh0PMUvJczoi+flxpnBEPxoER1IaAnU/NMPtT0= -github.com/klauspost/compress v1.17.10/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0= +github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc= +github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -132,8 +128,8 @@ github.com/power-devops/perfstat v0.0.0-20220216144756-c35f1ee13d7c h1:NRoLoZvkB github.com/power-devops/perfstat v0.0.0-20220216144756-c35f1ee13d7c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= -github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= -github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= +github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= +github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= github.com/shirou/gopsutil/v3 v3.24.4 h1:dEHgzZXt4LMNm+oYELpzl9YCqV65Yr/6SfrvgRBtXeU= github.com/shirou/gopsutil/v3 v3.24.4/go.mod h1:lTd2mdiOspcqLgAnr9/nGi71NkeMpWKdmhuxm9GusH8= github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM= @@ -145,16 +141,18 @@ github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVs github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/testcontainers/testcontainers-go v0.33.0 h1:zJS9PfXYT5O0ZFXM2xxXfk4J5UMw/kRiISng037Gxdw= -github.com/testcontainers/testcontainers-go v0.33.0/go.mod h1:W80YpTa8D5C3Yy16icheD01UTDu+LmXIA2Keo+jWtT8= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/testcontainers/testcontainers-go v0.35.0 h1:uADsZpTKFAtp8SLK+hMwSaa+X+JiERHtd4sQAFmXeMo= +github.com/testcontainers/testcontainers-go v0.35.0/go.mod h1:oEVBj5zrfJTrgjwONs1SsRbnBtH9OKl+IGl3UMcr2B4= github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY= github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= @@ -173,38 +171,40 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0= github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= -go.elastic.co/apm/v2 v2.6.2 h1:VBplAxgbOgTv+Giw/FS91xJpHYw/q8fz/XKPvqC+7/o= -go.elastic.co/apm/v2 v2.6.2/go.mod h1:33rOXgtHwbgZcDgi6I/GtCSMZQqgxkHC0IQT3gudKvo= +go.elastic.co/apm/v2 v2.6.3 h1:yVKFPLnmHOxpzLMGd3aexcik20ziXmRHqgcn9NZn/VU= +go.elastic.co/apm/v2 v2.6.3/go.mod h1:33rOXgtHwbgZcDgi6I/GtCSMZQqgxkHC0IQT3gudKvo= go.elastic.co/fastjson v1.4.0 h1:a4BXUKXZHAzjVOPrqtEx2FDsIRBCMek01vCnrtyutWs= go.elastic.co/fastjson v1.4.0/go.mod h1:ZD5um63l0/8TIdddZbL2znD83FAr2IckYa3KR7VcdNA= -go.opentelemetry.io/collector/pdata v1.17.0 h1:z8cjjT2FThAehWu5fbF48OnZyK5q8xd1UhC4XszDo0w= -go.opentelemetry.io/collector/pdata v1.17.0/go.mod h1:yZaQ9KZAm/qie96LTygRKxOXMq0/54h8OW7330ycuvQ= -go.opentelemetry.io/collector/semconv v0.111.0 h1:ELleMtLBzeZ3xhfhYPmFcLc0hJMqRxhOB0eY60WLivw= -go.opentelemetry.io/collector/semconv v0.111.0/go.mod h1:zCJ5njhWpejR+A40kiEoeFm1xq1uzyZwMnRNX6/D82A= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.55.0 h1:ZIg3ZT/aQ7AfKqdwp7ECpOK6vHqquXXuyTjIO8ZdmPs= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.55.0/go.mod h1:DQAwmETtZV00skUwgD6+0U89g80NKsJE3DCKeLLPQMI= -go.opentelemetry.io/otel v1.30.0 h1:F2t8sK4qf1fAmY9ua4ohFS/K+FUuOPemHUIXHtktrts= -go.opentelemetry.io/otel v1.30.0/go.mod h1:tFw4Br9b7fOS+uEao81PJjVMjW/5fvNCbpsDIXqP0pc= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.30.0 h1:WypxHH02KX2poqqbaadmkMYalGyy/vil4HE4PM4nRJc= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.30.0/go.mod h1:U79SV99vtvGSEBeeHnpgGJfTsnsdkWLpPN/CcHAzBSI= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.30.0 h1:VrMAbeJz4gnVDg2zEzjHG4dEH86j4jO6VYB+NgtGD8s= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.30.0/go.mod h1:qqN/uFdpeitTvm+JDqqnjm517pmQRYxTORbETHq5tOc= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.30.0 h1:lsInsfvhVIfOI6qHVyysXMNDnjO9Npvl7tlDPJFBVd4= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.30.0/go.mod h1:KQsVNh4OjgjTG0G6EiNi1jVpnaeeKsKMRwbLN+f1+8M= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.30.0 h1:m0yTiGDLUvVYaTFbAvCkVYIYcvwKt3G7OLoN77NUs/8= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.30.0/go.mod h1:wBQbT4UekBfegL2nx0Xk1vBcnzyBPsIVm9hRG4fYcr4= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.30.0 h1:umZgi92IyxfXd/l4kaDhnKgY8rnN/cZcF1LKc6I8OQ8= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.30.0/go.mod h1:4lVs6obhSVRb1EW5FhOuBTyiQhtRtAnnva9vD3yRfq8= -go.opentelemetry.io/otel/metric v1.30.0 h1:4xNulvn9gjzo4hjg+wzIKG7iNFEaBMX00Qd4QIZs7+w= -go.opentelemetry.io/otel/metric v1.30.0/go.mod h1:aXTfST94tswhWEb+5QjlSqG+cZlmyXy/u8jFpor3WqQ= -go.opentelemetry.io/otel/sdk v1.30.0 h1:cHdik6irO49R5IysVhdn8oaiR9m8XluDaJAs4DfOrYE= -go.opentelemetry.io/otel/sdk v1.30.0/go.mod h1:p14X4Ok8S+sygzblytT1nqG98QG2KYKv++HE0LY/mhg= -go.opentelemetry.io/otel/sdk/metric v1.30.0 h1:QJLT8Pe11jyHBHfSAgYH7kEmT24eX792jZO1bo4BXkM= -go.opentelemetry.io/otel/sdk/metric v1.30.0/go.mod h1:waS6P3YqFNzeP01kuo/MBBYqaoBJl7efRQHOaydhy1Y= -go.opentelemetry.io/otel/trace v1.30.0 h1:7UBkkYzeg3C7kQX8VAidWh2biiQbtAKjyIML8dQ9wmc= -go.opentelemetry.io/otel/trace v1.30.0/go.mod h1:5EyKqTzzmyqB9bwtCCq6pDLktPK6fmGf/Dph+8VI02o= -go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= -go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8= +go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= +go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= +go.opentelemetry.io/collector/pdata v1.24.0 h1:D6j92eAzmAbQgivNBUnt8r9juOl8ugb+ihYynoFZIEg= +go.opentelemetry.io/collector/pdata v1.24.0/go.mod h1:cf3/W9E/uIvPS4MR26SnMFJhraUCattzzM6qusuONuc= +go.opentelemetry.io/collector/semconv v0.118.0 h1:V4vlMIK7TIaemrrn2VawvQPwruIKpj7Xgw9P5+BL56w= +go.opentelemetry.io/collector/semconv v0.118.0/go.mod h1:N6XE8Q0JKgBN2fAhkUQtqK9LT7rEGR6+Wu/Rtbal1iI= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.56.0 h1:UP6IpuHFkUgOQL9FFQFrZ+5LiwhhYRbi7VZSIx6Nj5s= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.56.0/go.mod h1:qxuZLtbq5QDtdeSHsS7bcf6EH6uO6jUAgk764zd3rhM= +go.opentelemetry.io/otel v1.34.0 h1:zRLXxLCgL1WyKsPVrgbSdMN4c0FMkDAskSTQP+0hdUY= +go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.34.0 h1:ajl4QczuJVA2TU9W9AGw++86Xga/RKt//16z/yxPgdk= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.34.0/go.mod h1:Vn3/rlOJ3ntf/Q3zAI0V5lDnTbHGaUsNUeF6nZmm7pA= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.34.0 h1:opwv08VbCZ8iecIWs+McMdHRcAXzjAeda3uG2kI/hcA= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.34.0/go.mod h1:oOP3ABpW7vFHulLpE8aYtNBodrHhMTrvfxUXGvqm7Ac= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0 h1:OeNbIYk/2C15ckl7glBlOBp5+WlYsOElzTNmiPW/x60= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0/go.mod h1:7Bept48yIeqxP2OZ9/AqIpYS94h2or0aB4FypJTc8ZM= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0 h1:tgJ0uaNS4c98WRNUEx5U3aDlrDOI5Rs+1Vifcw4DJ8U= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0/go.mod h1:U7HYyW0zt/a9x5J1Kjs+r1f/d4ZHnYFclhYY2+YbeoE= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.34.0 h1:BEj3SPM81McUZHYjRS5pEgNgnmzGJ5tRpU5krWnV8Bs= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.34.0/go.mod h1:9cKLGBDzI/F3NoHLQGm4ZrYdIHsvGt6ej6hUowxY0J4= +go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ= +go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE= +go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A= +go.opentelemetry.io/otel/sdk v1.34.0/go.mod h1:0e/pNiaMAqaykJGKbi+tSjWfNNHMTxoC9qANsCzbyxU= +go.opentelemetry.io/otel/sdk/metric v1.34.0 h1:5CeK9ujjbFVL5c1PhLuStg1wxA7vQv7ce1EK0Gyvahk= +go.opentelemetry.io/otel/sdk/metric v1.34.0/go.mod h1:jQ/r8Ze28zRKoNRdkjCZxfs6YvBTG1+YIqyFVFYec5w= +go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k= +go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE= +go.opentelemetry.io/proto/otlp v1.5.0 h1:xJvq7gMzB31/d406fB8U5CBdyQGw4P399D1aQWU/3i4= +go.opentelemetry.io/proto/otlp v1.5.0/go.mod h1:keN8WnHxOy8PG0rQZjJJ5A2ebUoafqWp0eVQ4yIXvJ4= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= @@ -214,21 +214,21 @@ go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw= -golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U= +golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc= +golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4= -golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU= +golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0= +golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= -golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= +golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -241,16 +241,16 @@ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= -golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.25.0 h1:WtHI/ltw4NvSUig5KARz9h521QvRC8RmF/cuYqifU24= -golang.org/x/term v0.25.0/go.mod h1:RPyXicDX+6vLxogjjRxjgD2TKtmAO6NZBsBRfrOLu7M= +golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= +golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.28.0 h1:/Ts8HFuMR2E6IP/jlo7QVLZHggjKQbhu/7H0LJFr3Gg= +golang.org/x/term v0.28.0/go.mod h1:Sw/lC2IAUZ92udQNf3WodGtn4k/XoLyZoh8v/8uiwek= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= -golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= -golang.org/x/time v0.7.0 h1:ntUhktv3OPE6TgYxXWv9vKvUSJyIFJlyohwbkEwPrKQ= -golang.org/x/time v0.7.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= +golang.org/x/time v0.9.0 h1:EsRrnYcQiGH+5FfbgvV4AP7qEZstoyrHB0DzarOQ4ZY= +golang.org/x/time v0.9.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= @@ -259,14 +259,14 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 h1:hjSy6tcFQZ171igDaN5QHOw2n6vx40juYbC/x67CEhc= -google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:qpvKtACPCQhAdu3PyQgV4l3LMXZEtft7y8QcarRsp9I= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 h1:pPJltXNxVzT4pK9yD8vR9X75DaWYYmLGMsEvBfFQZzQ= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= -google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= -google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= -google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= -google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= +google.golang.org/genproto/googleapis/api v0.0.0-20250115164207-1a7da9e5054f h1:gap6+3Gk41EItBuyi4XX/bp4oqJ3UwuIMl25yGinuAA= +google.golang.org/genproto/googleapis/api v0.0.0-20250115164207-1a7da9e5054f/go.mod h1:Ic02D47M+zbarjYYUlK57y316f2MoN0gjAwI3f2S95o= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f h1:OxYkA3wjPsZyBylwymxSHa7ViiW1Sml4ToBrncvFehI= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f/go.mod h1:+2Yz8+CLJbIfL9z73EW45avw8Lmge3xVElCP9zEKi50= +google.golang.org/grpc v1.70.0 h1:pWFv03aZoHzlRKHWicjsZytKAiYCtNS0dHbXnIdq7jQ= +google.golang.org/grpc v1.70.0/go.mod h1:ofIJqVKDXx/JiXrwr2IG4/zwdH9txy3IlF40RmcJSQw= +google.golang.org/protobuf v1.36.3 h1:82DV7MYdb8anAVi3qge1wSnMDrnKK7ebr+I0hHRN1BU= +google.golang.org/protobuf v1.36.3/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/systemtest/instrumentation_test.go b/systemtest/instrumentation_test.go index c5305fefecf..09d67469e92 100644 --- a/systemtest/instrumentation_test.go +++ b/systemtest/instrumentation_test.go @@ -18,7 +18,6 @@ package systemtest_test import ( - "bytes" "encoding/json" "net/http" "net/http/httptest" @@ -138,11 +137,7 @@ func TestAPMServerInstrumentationAuth(t *testing.T) { systemtest.InvalidateAPIKeys(t) defer systemtest.InvalidateAPIKeys(t) - cmd := apiKeyCommand("create", "--name", t.Name(), "--json") - out, err := cmd.CombinedOutput() - require.NoError(t, err) - attrs := decodeJSONMap(t, bytes.NewReader(out)) - srv.Config.Instrumentation.APIKey = attrs["credentials"].(string) + srv.Config.Instrumentation.APIKey = systemtest.CreateAPIKey(t, t.Name(), []string{"config_agent:read", "sourcemap:write", "event:write"}) } err := srv.Start() diff --git a/systemtest/intake_test.go b/systemtest/intake_test.go index 8f271800688..6f5e6c263c7 100644 --- a/systemtest/intake_test.go +++ b/systemtest/intake_test.go @@ -18,7 +18,12 @@ package systemtest_test import ( + "context" + "strings" "testing" + "time" + + "github.com/stretchr/testify/require" "github.com/elastic/apm-server/systemtest" "github.com/elastic/apm-server/systemtest/apmservertest" @@ -73,3 +78,28 @@ func TestIntake(t *testing.T) { } } + +func TestIntakeMalformed(t *testing.T) { + // Setup a custom ingest pipeline to test a malformed data ingestion. + r, err := systemtest.Elasticsearch.Ingest.PutPipeline( + "traces-apm@custom", + strings.NewReader(`{"processors":[{"set":{"field":"span.duration.us","value":"poison"}}]}`), + ) + require.NoError(t, err) + require.False(t, r.IsError()) + defer systemtest.Elasticsearch.Ingest.DeletePipeline("traces-apm@custom") + // Test malformed intake data. + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + srv := apmservertest.NewServerTB(t) + systemtest.CleanupElasticsearch(t) + response := systemtest.SendBackendEventsPayload(t, srv.URL, "../testdata/intake-v2/spans.ndjson") + _, err = systemtest.Elasticsearch.SearchIndexMinDocs( + ctx, + response.Accepted, + "traces-apm*", + nil, + espoll.WithTimeout(10*time.Second), + ) + require.Error(t, err, "No traces should be indexed due to traces-apm@custom pipeline") +} diff --git a/systemtest/jaeger_test.go b/systemtest/jaeger_test.go deleted file mode 100644 index 8d8b5891a07..00000000000 --- a/systemtest/jaeger_test.go +++ /dev/null @@ -1,164 +0,0 @@ -// Licensed to Elasticsearch B.V. under one or more contributor -// license agreements. See the NOTICE file distributed with -// this work for additional information regarding copyright -// ownership. Elasticsearch B.V. licenses this file to you under -// the Apache License, Version 2.0 (the "License"); you may -// not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -package systemtest_test - -import ( - "context" - "encoding/json" - "fmt" - "net/url" - "os" - "testing" - - jaegermodel "github.com/jaegertracing/jaeger/model" - "github.com/jaegertracing/jaeger/proto-gen/api_v2" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - "github.com/tidwall/gjson" - "go.opentelemetry.io/otel" - "google.golang.org/grpc" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/credentials" - "google.golang.org/grpc/status" - - "github.com/elastic/apm-server/systemtest" - "github.com/elastic/apm-server/systemtest/apmservertest" - "github.com/elastic/apm-server/systemtest/estest" - "github.com/elastic/apm-tools/pkg/approvaltest" - "github.com/elastic/apm-tools/pkg/espoll" -) - -func TestJaeger(t *testing.T) { - srv := apmservertest.NewUnstartedServerTB(t) - srv.Config.Monitoring = newFastMonitoringConfig() - require.NoError(t, srv.Start()) - - for _, name := range []string{"batch_0", "batch_1"} { - t.Run(name, func(t *testing.T) { - systemtest.CleanupElasticsearch(t) - hits := sendJaegerBatch(t, srv, "../testdata/jaeger/"+name+".json", grpc.WithInsecure()) - approvaltest.ApproveFields(t, t.Name(), hits, "error.id") - }) - } - - fmt.Fprintf(os.Stdout, "%#v\n", otel.GetMeterProvider()) - doc := getBeatsMonitoringStats(t, srv, nil) - assert.GreaterOrEqual(t, gjson.GetBytes(doc.RawSource, "beats_stats.metrics.apm-server.jaeger.grpc.collect.request.count").Int(), int64(1)) -} - -func TestJaegerMuxedTLS(t *testing.T) { - systemtest.CleanupElasticsearch(t) - srv := apmservertest.NewUnstartedServerTB(t) - srv.Config.Monitoring = newFastMonitoringConfig() - srv.Config.TLS = &apmservertest.TLSConfig{ClientAuthentication: "required"} - require.NoError(t, srv.StartTLS()) - sendJaegerBatch(t, srv, - "../testdata/jaeger/batch_0.json", - grpc.WithTransportCredentials(credentials.NewTLS(srv.TLS)), - ) -} - -func sendJaegerBatch( - t *testing.T, srv *apmservertest.Server, - filename string, - dialOptions ...grpc.DialOption, -) []espoll.SearchHit { - conn, err := grpc.Dial(serverAddr(srv), dialOptions...) - require.NoError(t, err) - defer conn.Close() - - client := api_v2.NewCollectorServiceClient(conn) - request, err := decodeJaegerPostSpansRequest(filename) - require.NoError(t, err) - _, err = client.PostSpans(context.Background(), request) - require.NoError(t, err) - - expected := len(request.Batch.Spans) - for _, span := range request.Batch.Spans { - expected += len(span.GetLogs()) - } - - result := estest.ExpectMinDocs(t, systemtest.Elasticsearch, expected, "traces-apm*,logs-apm*", nil) - assert.Equal(t, expected, result.Hits.Total.Value) - return result.Hits.Hits -} - -func TestJaegerSampling(t *testing.T) { - systemtest.CleanupElasticsearch(t) - srv := apmservertest.NewServerTB(t) - - conn, err := grpc.Dial(serverAddr(srv), grpc.WithInsecure()) - require.NoError(t, err) - defer conn.Close() - - client := api_v2.NewSamplingManagerClient(conn) - _, err = client.GetSamplingStrategy( - context.Background(), &api_v2.SamplingStrategyParameters{ServiceName: "missing"}, - ) - require.Error(t, err) - assert.Regexp(t, "no sampling rate available", err.Error()) -} - -func TestJaegerAuth(t *testing.T) { - systemtest.CleanupElasticsearch(t) - srv := apmservertest.NewUnstartedServerTB(t) - srv.Config.AgentAuth.SecretToken = "secret" - require.NoError(t, srv.Start()) - - conn, err := grpc.Dial(serverAddr(srv), grpc.WithInsecure()) - require.NoError(t, err) - defer conn.Close() - - client := api_v2.NewCollectorServiceClient(conn) - request, err := decodeJaegerPostSpansRequest("../testdata/jaeger/batch_0.json") - require.NoError(t, err) - - // Attempt to send spans without the auth tag -- this should fail. - _, err = client.PostSpans(context.Background(), request) - require.Error(t, err) - status := status.Convert(err) - assert.Equal(t, codes.Unauthenticated, status.Code()) - - // Now with the auth tag -- this should succeed. - request.Batch.Process.Tags = append(request.Batch.Process.Tags, jaegermodel.KeyValue{ - Key: "elastic-apm-auth", - VType: jaegermodel.ValueType_STRING, - VStr: "Bearer secret", - }) - _, err = client.PostSpans(context.Background(), request) - require.NoError(t, err) - - estest.ExpectDocs(t, systemtest.Elasticsearch, "traces-apm*", espoll.BoolQuery{Filter: []interface{}{ - espoll.TermQuery{Field: "processor.event", Value: "transaction"}, - }}) -} - -func decodeJaegerPostSpansRequest(filename string) (*api_v2.PostSpansRequest, error) { - var request api_v2.PostSpansRequest - f, err := os.Open(filename) - if err != nil { - return nil, err - } - defer f.Close() - return &request, json.NewDecoder(f).Decode(&request) -} - -func serverAddr(srv *apmservertest.Server) string { - url, _ := url.Parse(srv.URL) - return url.Host -} diff --git a/systemtest/kibana.go b/systemtest/kibana.go index 3c73121808c..5384e875109 100644 --- a/systemtest/kibana.go +++ b/systemtest/kibana.go @@ -63,7 +63,7 @@ var ( IntegrationPackage *fleettest.Package ) -func init() { +func initKibana() { kibanaConfig := apmservertest.DefaultConfig().Kibana u, err := url.Parse(kibanaConfig.Host) if err != nil { diff --git a/systemtest/logging_test.go b/systemtest/logging_test.go index 0513dfdf379..0d48832a975 100644 --- a/systemtest/logging_test.go +++ b/systemtest/logging_test.go @@ -22,10 +22,10 @@ import ( "fmt" "io" "net/http" + "net/url" "strings" "testing" - "github.com/jaegertracing/jaeger/proto-gen/api_v2" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "go.elastic.co/apm/v2/apmtest" @@ -33,6 +33,7 @@ import ( "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc" "go.uber.org/zap/zapcore" "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" "github.com/elastic/apm-server/systemtest" "github.com/elastic/apm-server/systemtest/apmservertest" @@ -41,16 +42,11 @@ import ( func TestAPMServerGRPCRequestLoggingValid(t *testing.T) { systemtest.CleanupElasticsearch(t) srv := apmservertest.NewServerTB(t) - addr := serverAddr(srv) - conn, err := grpc.Dial(addr, grpc.WithInsecure()) + addr, err := url.Parse(srv.URL) require.NoError(t, err) - defer conn.Close() - - client := api_v2.NewCollectorServiceClient(conn) - request, err := decodeJaegerPostSpansRequest("../testdata/jaeger/batch_0.json") - require.NoError(t, err) - _, err = client.PostSpans(context.Background(), request) + conn, err := grpc.NewClient(addr.Host, grpc.WithTransportCredentials(insecure.NewCredentials())) require.NoError(t, err) + defer conn.Close() tracerProvider := newOTLPTracerProvider(newOTLPTraceExporter(t, srv, otlptracegrpc.WithHeaders( map[string]string{"Authorization": "Bearer abc123"}, @@ -60,14 +56,10 @@ func TestAPMServerGRPCRequestLoggingValid(t *testing.T) { srv.Close() - var foundGRPC, foundJaeger bool + var foundGRPC bool for _, entry := range srv.Logs.All() { if entry.Logger == "beater.grpc" { switch entry.Fields["grpc.request.method"] { - case "/jaeger.api_v2.CollectorService/PostSpans": - require.Equal(t, "beater.grpc", entry.Logger) - require.Equal(t, "OK", entry.Fields["grpc.response.status_code"]) - foundJaeger = true case "/opentelemetry.proto.collector.trace.v1.TraceService/Export": require.Equal(t, "beater.grpc", entry.Logger) require.Equal(t, "OK", entry.Fields["grpc.response.status_code"]) @@ -76,7 +68,6 @@ func TestAPMServerGRPCRequestLoggingValid(t *testing.T) { } } require.True(t, foundGRPC) - require.True(t, foundJaeger) } func TestAPMServerRequestLoggingValid(t *testing.T) { diff --git a/systemtest/main_test.go b/systemtest/main_test.go index c2a0bbbd937..584b83203c7 100644 --- a/systemtest/main_test.go +++ b/systemtest/main_test.go @@ -25,10 +25,14 @@ import ( func TestMain(m *testing.M) { log.Println("INFO: starting stack containers...") + initContainers() if err := StartStackContainers(); err != nil { log.Fatalf("failed to start stack containers: %v", err) } - + initElasticSearch() + initKibana() + initSettings() + initOTEL() log.Println("INFO: running system tests...") os.Exit(m.Run()) } diff --git a/systemtest/monitoring_test.go b/systemtest/monitoring_test.go index eae6541afd5..622a4e94af0 100644 --- a/systemtest/monitoring_test.go +++ b/systemtest/monitoring_test.go @@ -77,7 +77,9 @@ func TestMonitoring(t *testing.T) { metrics.Output = nil getBeatsMonitoringStats(t, srv, &metrics) acked := gjson.GetBytes(metrics.Libbeat, "output.events.acked") - return acked.Int() == N + // There may be additional pre-aggregated metrics indexed, + // hence we check >= rather than ==. + return acked.Int() >= N }, 10*time.Second, 10*time.Millisecond) // Assert the presence of output.write.bytes, and that it is non-zero; @@ -93,8 +95,8 @@ func TestMonitoring(t *testing.T) { assert.Equal(t, int64(0), gjson.GetBytes(metrics.Libbeat, "output.events.active").Int()) assert.Equal(t, int64(0), gjson.GetBytes(metrics.Libbeat, "output.events.failed").Int()) assert.Equal(t, int64(0), gjson.GetBytes(metrics.Libbeat, "output.events.toomany").Int()) - assert.Equal(t, int64(N), gjson.GetBytes(metrics.Libbeat, "output.events.total").Int()) - assert.Equal(t, int64(N), gjson.GetBytes(metrics.Libbeat, "pipeline.events.total").Int()) + assert.GreaterOrEqual(t, int64(N), gjson.GetBytes(metrics.Libbeat, "output.events.total").Int()) + assert.GreaterOrEqual(t, int64(N), gjson.GetBytes(metrics.Libbeat, "pipeline.events.total").Int()) assert.Equal(t, "elasticsearch", gjson.GetBytes(metrics.Libbeat, "output.type").Str) bulkRequestsAvailable := gjson.GetBytes(metrics.Output, "elasticsearch.bulk_requests.available") @@ -141,7 +143,7 @@ func getBeatsMonitoring(t testing.TB, srv *apmservertest.Server, type_ string, o espoll.TermQuery{Field: type_ + ".beat.uuid", Value: srv.BeatUUID}, ).WithSort("timestamp:desc") if _, err := req.Do(context.Background(), &result, espoll.WithCondition(result.Hits.MinHitsCondition(1))); err != nil { - t.Error(err) + t.Fatal(err) } var doc beatsMonitoringDoc diff --git a/systemtest/otlp.go b/systemtest/otlp.go new file mode 100644 index 00000000000..803c93eb9d1 --- /dev/null +++ b/systemtest/otlp.go @@ -0,0 +1,35 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package systemtest + +import "go.opentelemetry.io/otel" + +var OtelErrors = make(chan error, 1) + +func initOTEL() { + // otel.SetErrorHandler can only be called once per process. + otel.SetErrorHandler(otel.ErrorHandlerFunc(func(err error) { + if err == nil { + return + } + select { + case OtelErrors <- err: + default: + } + })) +} diff --git a/systemtest/otlp_test.go b/systemtest/otlp_test.go index 37996c01f3f..c709c6fb39b 100644 --- a/systemtest/otlp_test.go +++ b/systemtest/otlp_test.go @@ -20,12 +20,14 @@ package systemtest_test import ( "context" "errors" + "net/url" "testing" "time" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/tidwall/gjson" + "google.golang.org/grpc/credentials/insecure" "google.golang.org/grpc/metadata" "go.opentelemetry.io/collector/pdata/pcommon" @@ -34,7 +36,6 @@ import ( "go.opentelemetry.io/collector/pdata/pmetric" "go.opentelemetry.io/collector/pdata/pmetric/pmetricotlp" semconv "go.opentelemetry.io/collector/semconv/v1.5.0" - "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc" "go.opentelemetry.io/otel/exporters/otlp/otlptrace" @@ -58,21 +59,6 @@ import ( "github.com/elastic/apm-tools/pkg/espoll" ) -var otelErrors = make(chan error, 1) - -func init() { - // otel.SetErrorHandler can only be called once per process. - otel.SetErrorHandler(otel.ErrorHandlerFunc(func(err error) { - if err == nil { - return - } - select { - case otelErrors <- err: - default: - } - })) -} - func TestOTLPGRPCTraces(t *testing.T) { systemtest.CleanupElasticsearch(t) srv := apmservertest.NewServerTB(t) @@ -206,7 +192,7 @@ func TestOTLPGRPCMetrics(t *testing.T) { // opentelemetry-go does not support sending Summary metrics, // so we send them using the lower level OTLP/gRPC client. - conn, err := grpc.Dial(serverAddr(srv), grpc.WithInsecure(), grpc.WithBlock(), grpc.WithDefaultCallOptions(grpc.UseCompressor("gzip"))) + conn, err := grpc.NewClient(serverAddr(t, srv), grpc.WithTransportCredentials(insecure.NewCredentials()), grpc.WithDefaultCallOptions(grpc.UseCompressor("gzip"))) require.NoError(t, err) defer conn.Close() metricsClient := pmetricotlp.NewGRPCClient(conn) @@ -229,7 +215,7 @@ func TestOTLPGRPCMetrics(t *testing.T) { // Make sure we report monitoring for the metrics consumer. Metric values are unit tested. doc := getBeatsMonitoringStats(t, srv, nil) - assert.True(t, gjson.GetBytes(doc.RawSource, "beats_stats.metrics.apm-server.otlp.grpc.metrics.consumer").Exists()) + assert.Equal(t, int64(2), gjson.GetBytes(doc.RawSource, "beats_stats.metrics.apm-server.otlp.grpc.metrics.response.count").Int()) } func TestOTLPGRPCMetrics_partialSuccess(t *testing.T) { @@ -271,7 +257,7 @@ func TestOTLPGRPCLogs(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - conn, err := grpc.Dial(serverAddr(srv), grpc.WithInsecure(), grpc.WithBlock(), grpc.WithDefaultCallOptions(grpc.UseCompressor("gzip"))) + conn, err := grpc.NewClient(serverAddr(t, srv), grpc.WithTransportCredentials(insecure.NewCredentials()), grpc.WithDefaultCallOptions(grpc.UseCompressor("gzip"))) require.NoError(t, err) defer conn.Close() @@ -507,7 +493,7 @@ func TestOTLPGRPCLogsClientIP(t *testing.T) { md := metadata.New(map[string]string{"X-Forwarded-For": "89.160.20.128"}) ctx = metadata.NewOutgoingContext(ctx, md) - conn, err := grpc.Dial(serverAddr(srv), grpc.WithInsecure(), grpc.WithBlock(), grpc.WithDefaultCallOptions(grpc.UseCompressor("gzip"))) + conn, err := grpc.NewClient(serverAddr(t, srv), grpc.WithTransportCredentials(insecure.NewCredentials()), grpc.WithDefaultCallOptions(grpc.UseCompressor("gzip"))) require.NoError(t, err) defer conn.Close() @@ -553,7 +539,7 @@ func newMobileLogs(body interface{}) plog.Logs { } func newOTLPTraceExporter(t testing.TB, srv *apmservertest.Server, options ...otlptracegrpc.Option) *otlptrace.Exporter { - options = append(options, otlptracegrpc.WithEndpoint(serverAddr(srv)), otlptracegrpc.WithInsecure()) + options = append(options, otlptracegrpc.WithEndpoint(serverAddr(t, srv)), otlptracegrpc.WithInsecure()) exporter, err := otlptracegrpc.New(context.Background(), options...) require.NoError(t, err) t.Cleanup(func() { @@ -563,7 +549,7 @@ func newOTLPTraceExporter(t testing.TB, srv *apmservertest.Server, options ...ot } func newOTLPHTTPTraceExporter(t testing.TB, srv *apmservertest.Server, options ...otlptracehttp.Option) *otlptrace.Exporter { - options = append(options, otlptracehttp.WithEndpoint(serverAddr(srv)), otlptracehttp.WithInsecure()) + options = append(options, otlptracehttp.WithEndpoint(serverAddr(t, srv)), otlptracehttp.WithInsecure()) exporter, err := otlptracehttp.New(context.Background(), options...) require.NoError(t, err) t.Cleanup(func() { @@ -573,7 +559,7 @@ func newOTLPHTTPTraceExporter(t testing.TB, srv *apmservertest.Server, options . } func newOTLPMetricExporter(t testing.TB, srv *apmservertest.Server, options ...otlpmetricgrpc.Option) sdkmetric.Exporter { - options = append(options, otlpmetricgrpc.WithEndpoint(serverAddr(srv)), otlpmetricgrpc.WithInsecure()) + options = append(options, otlpmetricgrpc.WithEndpoint(serverAddr(t, srv)), otlpmetricgrpc.WithInsecure()) exporter, err := otlpmetricgrpc.New(context.Background(), options...) require.NoError(t, err) t.Cleanup(func() { @@ -623,13 +609,20 @@ func flushTracerProvider(ctx context.Context, tracerProvider *sdktrace.TracerPro return err } select { - case err := <-otelErrors: + case err := <-systemtest.OtelErrors: return err default: return nil } } +func serverAddr(t testing.TB, srv *apmservertest.Server) string { + t.Helper() + url, err := url.Parse(srv.URL) + require.NoError(t, err) + return url.Host +} + func sendOTLPMetrics( t testing.TB, ctx context.Context, @@ -653,7 +646,7 @@ func sendOTLPMetrics( return err } select { - case err := <-otelErrors: + case err := <-systemtest.OtelErrors: return err default: return nil diff --git a/systemtest/rum_test.go b/systemtest/rum_test.go index d48659dc205..db5af921e46 100644 --- a/systemtest/rum_test.go +++ b/systemtest/rum_test.go @@ -78,7 +78,10 @@ func TestRUMXForwardedFor(t *testing.T) { "source.port", // Do not assert the exact contents of the location field since they may change // slightly depending on the IP lookup. + "client.geo.city_name", "client.geo.location", + "client.geo.region_iso_code", + "client.geo.region_name", ) } diff --git a/systemtest/settings.go b/systemtest/settings.go new file mode 100644 index 00000000000..8d1384b8d8d --- /dev/null +++ b/systemtest/settings.go @@ -0,0 +1,55 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package systemtest + +import ( + "fmt" + "log" + "strings" +) + +func initSettings() { + // Proactively test with more strict + // "ignore_malformed" mode by default. + for _, t := range []string{ + "traces", + "metrics", + "logs-apm.error", + "logs-apm.app", + } { + if err := DisableIgnoreMalformed(t); err != nil { + log.Fatalf("failed to configure ignore_malformed %v", err) + } + } +} + +// DisableIgnoreMalformed updates component template index setting +// to disable "ignore_malformed" inside mappings. +func DisableIgnoreMalformed(componentTemplate string) error { + r, err := Elasticsearch.Cluster.PutComponentTemplate( + fmt.Sprintf("%s@custom", componentTemplate), + strings.NewReader(`{"template":{"settings":{"index":{"mapping":{"ignore_malformed":"false"}}}}}`), + ) + if err != nil { + return err + } + if r.IsError() { + return fmt.Errorf(`request to update "ignore_malformed":"false" failed for %s`, componentTemplate) + } + return nil +} diff --git a/testdata/jaeger/batch_0.json b/testdata/jaeger/batch_0.json deleted file mode 100644 index 32cbc9a216e..00000000000 --- a/testdata/jaeger/batch_0.json +++ /dev/null @@ -1,189 +0,0 @@ -{ - "batch": { - "spans": [ - { - "trace_id": "AAAAAAAAAAB74v2Y0Jc74w==", - "span_id": "e+L9mNCXO+M=", - "operation_name": "Driver::findNearest", - "references": null, - "flags": 1, - "start_time": "2019-12-20T07:41:44.953864Z", - "duration": 243417000, - "tags": [ - { - "key": "sampler.type", - "v_str": "const" - }, - { - "key": "sampler.param", - "v_type": 1, - "v_bool": true - }, - { - "key": "span.kind", - "v_str": "server" - }, - { - "key": "as", - "v_str": "thrift" - }, - { - "key": "peer.service", - "v_str": "driver-client" - }, - { - "key": "peer.ipv4", - "v_type": 2, - "v_int64": 2130706433 - }, - { - "key": "peer.port", - "v_type": 2, - "v_int64": 50535 - } - ], - "logs": [ - { - "timestamp": "2019-12-20T07:41:44.954043Z", - "fields": [ - { - "key": "event", - "v_str": "baggage" - }, - { - "key": "key", - "v_str": "customer" - }, - { - "key": "value", - "v_str": "Japanese Desserts" - } - ] - }, - { - "timestamp": "2019-12-20T07:41:44.95405Z", - "fields": [ - { - "key": "event", - "v_str": "Searching for nearby drivers" - }, - { - "key": "level", - "v_str": "info" - }, - { - "key": "location", - "v_str": "728,326" - } - ] - }, - { - "timestamp": "2019-12-20T07:41:45.007552Z", - "fields": [ - { - "key": "event", - "v_str": "Retrying GetDriver after error" - }, - { - "key": "level", - "v_str": "error" - }, - { - "key": "retry_no", - "v_type": 2, - "v_int64": 1 - }, - { - "key": "error", - "v_str": "redis timeout" - } - ] - }, - { - "timestamp": "2019-12-20T07:41:45.089431Z", - "fields": [ - { - "key": "event", - "v_str": "Retrying GetDriver after error" - }, - { - "key": "level", - "v_str": "error" - }, - { - "key": "retry_no", - "v_type": 2, - "v_int64": 1 - }, - { - "key": "error", - "v_str": "redis timeout" - } - ] - }, - { - "timestamp": "2019-12-20T07:41:45.17253Z", - "fields": [ - { - "key": "event", - "v_str": "Retrying GetDriver after error" - }, - { - "key": "level", - "v_str": "error" - }, - { - "key": "retry_no", - "v_type": 2, - "v_int64": 1 - }, - { - "key": "error", - "v_str": "redis timeout" - } - ] - }, - { - "timestamp": "2019-12-20T07:41:45.197117Z", - "fields": [ - { - "key": "event", - "v_str": "Search successful" - }, - { - "key": "level", - "v_str": "info" - }, - { - "key": "num_drivers", - "v_type": 2, - "v_int64": 10 - } - ] - } - ] - } - ], - "process": { - "service_name": "driver", - "tags": [ - { - "key": "jaeger.version", - "v_str": "Go-2.20.1" - }, - { - "key": "hostname", - "v_str": "host01" - }, - { - "key": "ip", - "v_str": "10.0.0.13" - }, - { - "key": "client-uuid", - "v_str": "624386e9c81d2980" - } - ] - } - } -} diff --git a/testdata/jaeger/batch_0_authorization.json b/testdata/jaeger/batch_0_authorization.json deleted file mode 100644 index b2ea9d73ab7..00000000000 --- a/testdata/jaeger/batch_0_authorization.json +++ /dev/null @@ -1,193 +0,0 @@ -{ - "batch": { - "spans": [ - { - "trace_id": "AAAAAAAAAAB74v2Y0Jc74w==", - "span_id": "e+L9mNCXO+M=", - "operation_name": "Driver::findNearest", - "references": null, - "flags": 1, - "start_time": "2019-12-20T07:41:44.953864Z", - "duration": 243417000, - "tags": [ - { - "key": "sampler.type", - "v_str": "const" - }, - { - "key": "sampler.param", - "v_type": 1, - "v_bool": true - }, - { - "key": "span.kind", - "v_str": "server" - }, - { - "key": "as", - "v_str": "thrift" - }, - { - "key": "peer.service", - "v_str": "driver-client" - }, - { - "key": "peer.ipv4", - "v_type": 2, - "v_int64": 2130706433 - }, - { - "key": "peer.port", - "v_type": 2, - "v_int64": 50535 - } - ], - "logs": [ - { - "timestamp": "2019-12-20T07:41:44.954043Z", - "fields": [ - { - "key": "event", - "v_str": "baggage" - }, - { - "key": "key", - "v_str": "customer" - }, - { - "key": "value", - "v_str": "Japanese Desserts" - } - ] - }, - { - "timestamp": "2019-12-20T07:41:44.95405Z", - "fields": [ - { - "key": "event", - "v_str": "Searching for nearby drivers" - }, - { - "key": "level", - "v_str": "info" - }, - { - "key": "location", - "v_str": "728,326" - } - ] - }, - { - "timestamp": "2019-12-20T07:41:45.007552Z", - "fields": [ - { - "key": "event", - "v_str": "Retrying GetDriver after error" - }, - { - "key": "level", - "v_str": "error" - }, - { - "key": "retry_no", - "v_type": 2, - "v_int64": 1 - }, - { - "key": "error", - "v_str": "redis timeout" - } - ] - }, - { - "timestamp": "2019-12-20T07:41:45.089431Z", - "fields": [ - { - "key": "event", - "v_str": "Retrying GetDriver after error" - }, - { - "key": "level", - "v_str": "error" - }, - { - "key": "retry_no", - "v_type": 2, - "v_int64": 1 - }, - { - "key": "error", - "v_str": "redis timeout" - } - ] - }, - { - "timestamp": "2019-12-20T07:41:45.17253Z", - "fields": [ - { - "key": "event", - "v_str": "Retrying GetDriver after error" - }, - { - "key": "level", - "v_str": "error" - }, - { - "key": "retry_no", - "v_type": 2, - "v_int64": 1 - }, - { - "key": "error", - "v_str": "redis timeout" - } - ] - }, - { - "timestamp": "2019-12-20T07:41:45.197117Z", - "fields": [ - { - "key": "event", - "v_str": "Search successful" - }, - { - "key": "level", - "v_str": "info" - }, - { - "key": "num_drivers", - "v_type": 2, - "v_int64": 10 - } - ] - } - ] - } - ], - "process": { - "service_name": "driver", - "tags": [ - { - "key": "jaeger.version", - "v_str": "Go-2.20.1" - }, - { - "key": "hostname", - "v_str": "host01" - }, - { - "key": "ip", - "v_str": "10.0.0.13" - }, - { - "key": "client-uuid", - "v_str": "624386e9c81d2980" - }, - { - "key": "authorization", - "v_str": "Bearer 1234" - } - ] - } - } -} diff --git a/testdata/jaeger/batch_1.json b/testdata/jaeger/batch_1.json deleted file mode 100644 index cb7e218ff08..00000000000 --- a/testdata/jaeger/batch_1.json +++ /dev/null @@ -1,472 +0,0 @@ -{ - "batch": { - "spans": [ - { - "trace_id": "AAAAAAAAAAB74v2Y0Jc74w==", - "span_id": "bgnovO/WuCg=", - "operation_name": "FindDriverIDs", - "references": [ - { - "trace_id": "AAAAAAAAAAB74v2Y0Jc74w==", - "span_id": "e+L9mNCXO+M=" - } - ], - "flags": 1, - "start_time": "2019-12-20T07:41:44.954062Z", - "duration": 19711000, - "tags": [ - { - "key": "param.location", - "v_str": "728,326" - }, - { - "key": "span.kind", - "v_str": "client" - } - ], - "logs": [ - { - "timestamp": "2019-12-20T07:41:44.973728Z", - "fields": [ - { - "key": "event", - "v_str": "Found drivers" - }, - { - "key": "level", - "v_str": "info" - } - ] - } - ] - }, - { - "trace_id": "AAAAAAAAAAB74v2Y0Jc74w==", - "span_id": "MzKVv7Q46gM=", - "operation_name": "GetDriver", - "references": [ - { - "trace_id": "AAAAAAAAAAB74v2Y0Jc74w==", - "span_id": "e+L9mNCXO+M=" - } - ], - "flags": 1, - "start_time": "2019-12-20T07:41:44.973809Z", - "duration": 33732000, - "tags": [ - { - "key": "param.driverID", - "v_str": "T762465C" - }, - { - "key": "span.kind", - "v_str": "client" - }, - { - "key": "error", - "v_type": 1, - "v_bool": true - } - ], - "logs": [ - { - "timestamp": "2019-12-20T07:41:45.006847Z", - "fields": [ - { - "key": "event", - "v_str": "redis timeout" - }, - { - "key": "level", - "v_str": "error" - }, - { - "key": "driver_id", - "v_str": "T762465C" - }, - { - "key": "error", - "v_str": "redis timeout" - } - ] - } - ] - }, - { - "trace_id": "AAAAAAAAAAB74v2Y0Jc74w==", - "span_id": "Ynw3qX5HXC8=", - "operation_name": "GetDriver", - "references": [ - { - "trace_id": "AAAAAAAAAAB74v2Y0Jc74w==", - "span_id": "e+L9mNCXO+M=" - } - ], - "flags": 1, - "start_time": "2019-12-20T07:41:45.007578Z", - "duration": 9240000, - "tags": [ - { - "key": "param.driverID", - "v_str": "T762465C" - }, - { - "key": "span.kind", - "v_str": "client" - } - ], - "logs": null - }, - { - "trace_id": "AAAAAAAAAAB74v2Y0Jc74w==", - "span_id": "e9dmPTnFqEc=", - "operation_name": "GetDriver", - "references": [ - { - "trace_id": "AAAAAAAAAAB74v2Y0Jc74w==", - "span_id": "e+L9mNCXO+M=" - } - ], - "flags": 1, - "start_time": "2019-12-20T07:41:45.016845Z", - "duration": 12561000, - "tags": [ - { - "key": "param.driverID", - "v_str": "T712515C" - }, - { - "key": "span.kind", - "v_str": "client" - } - ], - "logs": null - }, - { - "trace_id": "AAAAAAAAAAB74v2Y0Jc74w==", - "span_id": "a0BR3SpeI2Y=", - "operation_name": "GetDriver", - "references": [ - { - "trace_id": "AAAAAAAAAAB74v2Y0Jc74w==", - "span_id": "e+L9mNCXO+M=" - } - ], - "flags": 1, - "start_time": "2019-12-20T07:41:45.029415Z", - "duration": 10630000, - "tags": [ - { - "key": "param.driverID", - "v_str": "T752110C" - }, - { - "key": "span.kind", - "v_str": "client" - } - ], - "logs": null - }, - { - "trace_id": "AAAAAAAAAAB74v2Y0Jc74w==", - "span_id": "bfl6hrmzRRs=", - "operation_name": "GetDriver", - "references": [ - { - "trace_id": "AAAAAAAAAAB74v2Y0Jc74w==", - "span_id": "e+L9mNCXO+M=" - } - ], - "flags": 1, - "start_time": "2019-12-20T07:41:45.040082Z", - "duration": 13946000, - "tags": [ - { - "key": "param.driverID", - "v_str": "T757670C" - }, - { - "key": "span.kind", - "v_str": "client" - } - ], - "logs": null - }, - { - "trace_id": "AAAAAAAAAAB74v2Y0Jc74w==", - "span_id": "YUgR1sSYv7A=", - "operation_name": "GetDriver", - "references": [ - { - "trace_id": "AAAAAAAAAAB74v2Y0Jc74w==", - "span_id": "e+L9mNCXO+M=" - } - ], - "flags": 1, - "start_time": "2019-12-20T07:41:45.054046Z", - "duration": 35375000, - "tags": [ - { - "key": "param.driverID", - "v_str": "T781861C" - }, - { - "key": "span.kind", - "v_str": "client" - }, - { - "key": "error", - "v_type": 1, - "v_bool": true - } - ], - "logs": [ - { - "timestamp": "2019-12-20T07:41:45.089372Z", - "fields": [ - { - "key": "event", - "v_str": "redis timeout" - }, - { - "key": "level", - "v_str": "error" - }, - { - "key": "driver_id", - "v_str": "T781861C" - }, - { - "key": "error", - "v_str": "redis timeout" - } - ] - } - ] - }, - { - "trace_id": "AAAAAAAAAAB74v2Y0Jc74w==", - "span_id": "IxYEVZ2oTWE=", - "operation_name": "GetDriver", - "references": [ - { - "trace_id": "AAAAAAAAAAB74v2Y0Jc74w==", - "span_id": "e+L9mNCXO+M=" - } - ], - "flags": 1, - "start_time": "2019-12-20T07:41:45.089459Z", - "duration": 11802000, - "tags": [ - { - "key": "param.driverID", - "v_str": "T781861C" - }, - { - "key": "span.kind", - "v_str": "client" - } - ], - "logs": null - }, - { - "trace_id": "AAAAAAAAAAB74v2Y0Jc74w==", - "span_id": "Yffs8k0Tw2o=", - "operation_name": "GetDriver", - "references": [ - { - "trace_id": "AAAAAAAAAAB74v2Y0Jc74w==", - "span_id": "e+L9mNCXO+M=" - } - ], - "flags": 1, - "start_time": "2019-12-20T07:41:45.101278Z", - "duration": 12236000, - "tags": [ - { - "key": "param.driverID", - "v_str": "T705860C" - }, - { - "key": "span.kind", - "v_str": "client" - } - ], - "logs": null - }, - { - "trace_id": "AAAAAAAAAAB74v2Y0Jc74w==", - "span_id": "LvM1utJKzMI=", - "operation_name": "GetDriver", - "references": [ - { - "trace_id": "AAAAAAAAAAB74v2Y0Jc74w==", - "span_id": "e+L9mNCXO+M=" - } - ], - "flags": 1, - "start_time": "2019-12-20T07:41:45.113531Z", - "duration": 11986000, - "tags": [ - { - "key": "param.driverID", - "v_str": "T708771C" - }, - { - "key": "span.kind", - "v_str": "client" - } - ], - "logs": null - }, - { - "trace_id": "AAAAAAAAAAB74v2Y0Jc74w==", - "span_id": "OOxkXnIBIk0=", - "operation_name": "GetDriver", - "references": [ - { - "trace_id": "AAAAAAAAAAB74v2Y0Jc74w==", - "span_id": "e+L9mNCXO+M=" - } - ], - "flags": 1, - "start_time": "2019-12-20T07:41:45.125567Z", - "duration": 7311000, - "tags": [ - { - "key": "param.driverID", - "v_str": "T710624C" - }, - { - "key": "span.kind", - "v_str": "client" - } - ], - "logs": null - }, - { - "trace_id": "AAAAAAAAAAB74v2Y0Jc74w==", - "span_id": "AkLuN3TZ6rE=", - "operation_name": "GetDriver", - "references": [ - { - "trace_id": "AAAAAAAAAAB74v2Y0Jc74w==", - "span_id": "e+L9mNCXO+M=" - } - ], - "flags": 1, - "start_time": "2019-12-20T07:41:45.132896Z", - "duration": 39602000, - "tags": [ - { - "key": "param.driverID", - "v_str": "T752547C" - }, - { - "key": "span.kind", - "v_str": "client" - }, - { - "key": "error", - "v_type": 1, - "v_bool": true - } - ], - "logs": [ - { - "timestamp": "2019-12-20T07:41:45.172347Z", - "fields": [ - { - "key": "event", - "v_str": "redis timeout" - }, - { - "key": "level", - "v_str": "error" - }, - { - "key": "driver_id", - "v_str": "T752547C" - }, - { - "key": "error", - "v_str": "redis timeout" - } - ] - } - ] - }, - { - "trace_id": "AAAAAAAAAAB74v2Y0Jc74w==", - "span_id": "amPR6Bz8fZU=", - "operation_name": "GetDriver", - "references": [ - { - "trace_id": "AAAAAAAAAAB74v2Y0Jc74w==", - "span_id": "e+L9mNCXO+M=" - } - ], - "flags": 1, - "start_time": "2019-12-20T07:41:45.172618Z", - "duration": 14029000, - "tags": [ - { - "key": "param.driverID", - "v_str": "T752547C" - }, - { - "key": "span.kind", - "v_str": "client" - } - ], - "logs": null - }, - { - "trace_id": "AAAAAAAAAAB74v2Y0Jc74w==", - "span_id": "K0wo8CsnLxc=", - "operation_name": "GetDriver", - "references": [ - { - "trace_id": "AAAAAAAAAAB74v2Y0Jc74w==", - "span_id": "e+L9mNCXO+M=" - } - ], - "flags": 1, - "start_time": "2019-12-20T07:41:45.18667Z", - "duration": 10431000, - "tags": [ - { - "key": "param.driverID", - "v_str": "T757338C" - }, - { - "key": "span.kind", - "v_str": "client" - } - ], - "logs": null - } - ], - "process": { - "service_name": "redis", - "tags": [ - { - "key": "jaeger.version", - "v_str": "Go-2.20.1" - }, - { - "key": "hostname", - "v_str": "host01" - }, - { - "key": "ip", - "v_str": "10.0.0.13" - }, - { - "key": "client-uuid", - "v_str": "2e3f8db3eb77fae0" - } - ] - } - } -} diff --git a/testdata/jaeger/span.thrift b/testdata/jaeger/span.thrift deleted file mode 100644 index c45a2901be5..00000000000 Binary files a/testdata/jaeger/span.thrift and /dev/null differ diff --git a/testing/apmsoak/Makefile b/testing/apmsoak/Makefile index a3302140970..12d1bf8438e 100644 --- a/testing/apmsoak/Makefile +++ b/testing/apmsoak/Makefile @@ -14,7 +14,7 @@ terraform.tfvars: .PHONY: use-production use-production: - @terraform workspace select production || terraform worksapce new production + @terraform workspace select production || terraform workspace new production .PHONY: apmsoak apmsoak: diff --git a/testing/benchmark/Makefile b/testing/benchmark/Makefile index 9baf132edaf..b368edcefc3 100644 --- a/testing/benchmark/Makefile +++ b/testing/benchmark/Makefile @@ -111,6 +111,7 @@ log-benckmark-profile: .PHONY: run-benchmark run-benchmark: log-benckmark-profile @ssh $(SSH_OPTS) -i $(SSH_KEY) $(SSH_USER)@$(WORKER_IP) ". .envrc && bin/apmbench -run='$(BENCHMARK_RUN)' \ + -rewrite-timestamps -rewrite-ids \ -benchtime=$(BENCHMARK_TIME) -count=$(BENCHMARK_COUNT) -warmup-time=$(BENCHMARK_WARMUP_TIME) \ -agents=$(BENCHMARK_AGENTS) -detailed=$(BENCHMARK_DETAILED) -event-rate=$(BENCHMARK_EVENT_RATE) -cpuprofile=$(BENCHMARK_CPU_OUT)" 2>&1 | tee $(BENCHMARK_RESULT) diff --git a/testing/benchmark/README.md b/testing/benchmark/README.md index c3cf50297e6..62139f6e881 100644 --- a/testing/benchmark/README.md +++ b/testing/benchmark/README.md @@ -76,43 +76,34 @@ The main commands are: Helper commands - `~/.ssh/id_rsa_terraform`: Generates a new SSH key without passphrase for the worker VMs. -- `terraform.tfvars`: Copies the examples tfvars and sets the `user_name` var with to `$USER`. +- `terraform.tfvars`: + - Set `TFVARS_SOURCE` to use an explicit profile + - Otherwise the `terraform.tfvars.example` file is used + - Sets the `USER_NAME` var to `$USER`. - `apmbench`: Compiles the `apmbench` binary from the provided location (`APMBENCH_PATH`). -### Override the docker image and image tag +### Override Docker Image -Running `make docker-override-committed-version` will create new docker images for `kibana` and `elastic-agent` -with local `apm` package and `apm-server` and a Terraform variable file. The file named -`docker_image.auto.tfvars` contains Terraform Docker image Terraform variables overrides. This file is not -overridden automatically, you need to remove it manually if present. +There are two ways to override the docker images (or tags) that Terraform will provision: -#### Override docker image tag +1. **Manual**: To use an already existing container, change the values of the `docker_image_override` (or `docker_image_tag_override`) field in the profile defined by `TFVARS_SOURCE` (default is `terraform.tfvars`). -It is possible to override the tag of the docker image that is run in the remote ESS deployment. You can -specify any of the available tags (such as `8.3.0-SNAPSHOT` or a more specific tag `8.3.0-c655cda8-SNAPSHOT`). -Alternatively, you can run `make docker-override-committed-version` in your shell, to have use the committed -tags in the `docker-compose.yml` file in the repository root. - -#### Override the docker image - -It is also possible to override the docker image to one that is allowed to run in ESS. For more information -on which repositories can be used, please refer to our internal docs. To override the docker image, you'll need -to specify the full object of images that is defined in `variables.tf`: `docker_image_override`. -Alternatively, you can run `make docker-override-committed-version` in your shell, to have use the committed -tags in the `docker-compose.yml` file in the repository root. +2. **Automatic**: To encode local changes in `apm-server`, run `make docker-override-committed-version`. + - This will build and push a new set of docker images to the internal docker registery. + - If `IMAGE_TAG` is not set, the committed tags will be used as defined in `docker-compose.yml` in the repository root. + - The file `docker_image.auto.tfvars` contains the Terraform variable overrides for the defined docker images. No need to override them manualy. + - This file is not overridden automatically, you need to remove it manually if present. ### Set APM index shards -By default, the APM indices ship with `number_of_shards` set to `1`. To override this behavior, you can modify the -`apm_shards` variable and individually set the setting for each of the component templates. See an example of how to -do that in `terraform.tfvars.example`. +By default, the APM indices ship with `number_of_shards` set to `1`. To override this behavior, you can modify the `apm_shards` variable and individually set the setting for each of the component templates. See an example of how to do that in `terraform.tfvars.example`. ### Delete all the APM data streams -`make cleanup-elasticsearch` will delete all the APM data streams. This may be useful in case you'd like to re-run -the benchmarks without destroying the deployment. +`make cleanup-elasticsearch` will delete all the APM data streams. This may be useful in case you'd like to re-run the benchmarks without destroying the deployment. ### Slack reporting + Reporting data is taken from the https://``/app/dashboards#/view/a5bc8390-2f8e-11ed-a369-052d8245fa04?_g=(filters:!(),refreshInterval:(pause:!t,value:0),time:(from:now-30d,to:now)) It's possible to add or modify any metric. diff --git a/testing/benchmark/main.tf b/testing/benchmark/main.tf index 4b888e7a78a..713eb4725db 100644 --- a/testing/benchmark/main.tf +++ b/testing/benchmark/main.tf @@ -26,13 +26,14 @@ locals { build = var.BUILD_ID created_date = coalesce(var.CREATED_DATE, time_static.created_date.unix) } + project = "apm-server-benchmarks" } module "tags" { source = "../infra/terraform/modules/tags" # use the convention for team/shared owned resources if we are running in CI. # assume this is an individually owned resource otherwise. - project = startswith(var.user_name, "benchci") ? "benchmarks" : var.user_name + project = startswith(var.user_name, "benchci") ? local.project : "${local.project}-${var.user_name}" } provider "ec" {} @@ -93,12 +94,14 @@ module "ec_deployment" { deployment_template = var.deployment_template deployment_name_prefix = local.name_prefix - apm_server_size = var.apm_server_size - apm_server_zone_count = var.apm_server_zone_count - apm_index_shards = var.apm_shards - drop_pipeline = var.drop_pipeline - apm_server_expvar = true - apm_server_pprof = true + apm_server_size = var.apm_server_size + apm_server_zone_count = var.apm_server_zone_count + apm_index_shards = var.apm_shards + drop_pipeline = var.drop_pipeline + apm_server_expvar = true + apm_server_pprof = true + apm_server_tail_sampling = var.apm_server_tail_sampling + apm_server_tail_sampling_storage_limit = var.apm_server_tail_sampling_storage_limit elasticsearch_size = var.elasticsearch_size elasticsearch_zone_count = var.elasticsearch_zone_count @@ -152,9 +155,14 @@ module "standalone_apm_server" { vpc_id = module.vpc.vpc_id aws_os = "amzn2-ami-hvm-*-x86_64-ebs" apm_instance_type = var.standalone_apm_server_instance_size + apm_volume_type = var.standalone_apm_server_volume_type + apm_volume_size = var.apm_server_tail_sampling ? coalesce(var.standalone_apm_server_volume_size, 60) : var.standalone_apm_server_volume_size apm_server_bin_path = var.apm_server_bin_path ea_managed = false + apm_server_tail_sampling = var.apm_server_tail_sampling + apm_server_tail_sampling_storage_limit = var.apm_server_tail_sampling_storage_limit + aws_provisioner_key_name = var.private_key elasticsearch_url = module.moxy[0].moxy_url diff --git a/testing/benchmark/outputs.tf b/testing/benchmark/outputs.tf index 2cad7994126..a2f40c81e43 100644 --- a/testing/benchmark/outputs.tf +++ b/testing/benchmark/outputs.tf @@ -43,6 +43,6 @@ output "apm_server_ip" { } output "admin_console_url" { - value = var.run_standalone ? "" : module.ec_deployment[0].admin_console_url + value = var.run_standalone ? "https://cloud.elastic.co/deployments" : module.ec_deployment[0].admin_console_url description = "The admin console URL" } diff --git a/testing/benchmark/terraform.tfvars.example b/testing/benchmark/terraform.tfvars.example index 2b44a828d6c..98cf1ca668e 100644 --- a/testing/benchmark/terraform.tfvars.example +++ b/testing/benchmark/terraform.tfvars.example @@ -22,6 +22,10 @@ user_name = "USER" # The number of AZs the APM Server should span. # apm_server_zone_count = 2 +# Tail-based sampling settings of the APM Server. +# apm_server_tail_sampling = false +# apm_server_tail_sampling_storage_limit = "10GB" + # The Elasticsearch cluster node size. # elasticsearch_size = "1g" @@ -71,5 +75,9 @@ user_name = "USER" # Override the default APM Server VM size in standalone bench mode. # standalone_apm_server_instance_size = "c6i.2xlarge" +# Override the default APM Server VM volume settings in standalone bench mode +# standalone_apm_server_volume_type = "gp2" +# standalone_apm_server_volume_size = 8 + # Override the default Moxy VM size in standalone bench mode. -# standalone_moxy_instance_size = "c6i.4xlarge" \ No newline at end of file +# standalone_moxy_instance_size = "c6i.4xlarge" diff --git a/testing/benchmark/variables.tf b/testing/benchmark/variables.tf index b06a4d7a6b2..25671ad3253 100644 --- a/testing/benchmark/variables.tf +++ b/testing/benchmark/variables.tf @@ -20,7 +20,7 @@ variable "ess_region" { } variable "deployment_template" { - default = "gcp-compute-optimized-v3" + default = "gcp-cpu-optimized" description = "Optional deployment template. Defaults to the CPU optimized template for GCP" type = string } @@ -92,6 +92,18 @@ variable "drop_pipeline" { type = bool } +variable "apm_server_tail_sampling" { + default = false + description = "Whether or not to enable APM Server tail-based sampling. Defaults to false" + type = bool +} + +variable "apm_server_tail_sampling_storage_limit" { + default = "10GB" + description = "Storage size limit of APM Server tail-based sampling. Defaults to 10GB" + type = string +} + # Standalone variable "apm_server_bin_path" { @@ -118,6 +130,18 @@ variable "standalone_moxy_instance_size" { description = "Optional instance type to use for moxy VM" } +variable "standalone_apm_server_volume_type" { + default = "gp3" + type = string + description = "Optional volume type to use for APM Server VM" +} + +variable "standalone_apm_server_volume_size" { + default = null + type = number + description = "Optional volume size in GB to use for APM Server VM" +} + ## VPC Network settings variable "vpc_cidr" { diff --git a/testing/cloud/Makefile b/testing/cloud/Makefile index 6116b928bfe..fb01cbdbb31 100644 --- a/testing/cloud/Makefile +++ b/testing/cloud/Makefile @@ -27,9 +27,9 @@ USER_KIBANA_DOCKER_IMAGE=docker.elastic.co/observability-ci/${USER_NAME}-kibana # use in the deployment. ############################################################################## -docker_image.auto.tfvars: kibana_docker_image elastic_agent_docker_image +docker_image.auto.tfvars: elastic_agent_docker_image @echo 'docker_image_override={"elasticsearch":"${ELASTICSEARCH_DOCKER_IMAGE}","kibana":"${KIBANA_DOCKER_IMAGE}","apm":"${CI_ELASTIC_AGENT_DOCKER_IMAGE}"}' > $@ - @echo 'docker_image_tag_override={"elasticsearch":"${IMAGE_TAG}","kibana":"${CUSTOM_IMAGE_TAG}","apm":"${CUSTOM_IMAGE_TAG}"}' >> $@ + @echo 'docker_image_tag_override={"elasticsearch":"${IMAGE_TAG}","kibana":"${IMAGE_TAG}","apm":"${CUSTOM_IMAGE_TAG}"}' >> $@ ############################################################################## # Terraform shortcut rules. diff --git a/testing/cloud/main.tf b/testing/cloud/main.tf index ba64172c9a1..2589f50d7ef 100644 --- a/testing/cloud/main.tf +++ b/testing/cloud/main.tf @@ -8,6 +8,11 @@ terraform { } } +module "tags" { + source = "../infra/terraform/modules/tags" + project = "cloud" +} + provider "ec" {} locals { @@ -39,4 +44,6 @@ module "ec_deployment" { "kibana" : coalesce(var.docker_image_tag_override["kibana"], local.docker_image_tag), "apm" : coalesce(var.docker_image_tag_override["apm"], local.docker_image_tag) } + + tags = module.tags.tags } diff --git a/testing/cloud/variables.tf b/testing/cloud/variables.tf index fafb0c716c9..6ced0624820 100644 --- a/testing/cloud/variables.tf +++ b/testing/cloud/variables.tf @@ -7,7 +7,7 @@ variable "ess_region" { } variable "deployment_template" { - default = "gcp-compute-optimized-v3" + default = "gcp-cpu-optimized" description = "Optional deployment template. Defaults to the CPU optimized template for GCP" type = string } diff --git a/testing/docker/elastic-agent/build.sh b/testing/docker/elastic-agent/build.sh old mode 100644 new mode 100755 diff --git a/testing/docker/elasticsearch/roles.yml b/testing/docker/elasticsearch/roles.yml index 40484d004b5..f19fa98a90b 100644 --- a/testing/docker/elasticsearch/roles.yml +++ b/testing/docker/elasticsearch/roles.yml @@ -3,7 +3,7 @@ apm_server: indices: - names: ['apm-*', 'traces-apm*', 'logs-apm*', 'metrics-apm*'] privileges: ['write','create_index','manage','manage_ilm'] - - names: ['.apm-source-map'] + - names: ['.apm-source-map', 'traces-apm.sampled*'] privileges: ['read'] applications: - application: 'apm' diff --git a/testing/docker/elasticsearch/users_roles b/testing/docker/elasticsearch/users_roles index 3330a232190..08ab802feb8 100644 --- a/testing/docker/elasticsearch/users_roles +++ b/testing/docker/elasticsearch/users_roles @@ -1,6 +1,5 @@ apm_server:apm_server_user apm_system:apm_server_user -apm_user:apm_server_user,apm_user_ro beats:beats_user beats_system:beats_user,filebeat_user,heartbeat_user,metricbeat_user filebeat:filebeat_user diff --git a/testing/infra/k8s/base/stack/apm-server.yaml b/testing/infra/k8s/base/stack/apm-server.yaml index 1e09530424e..82fd4ea9903 100644 --- a/testing/infra/k8s/base/stack/apm-server.yaml +++ b/testing/infra/k8s/base/stack/apm-server.yaml @@ -4,7 +4,7 @@ metadata: name: apm-server spec: # TODO: replace with a pinned version such as 9.0.0-aaaaaaaa-SNAPSHOT - version: 9.0.0-3b9dafe0-SNAPSHOT + version: 9.0.0-faf48818-SNAPSHOT count: 1 http: tls: diff --git a/testing/infra/k8s/base/stack/elasticsearch.yaml b/testing/infra/k8s/base/stack/elasticsearch.yaml index bde2ea7ed20..6041e6acc21 100644 --- a/testing/infra/k8s/base/stack/elasticsearch.yaml +++ b/testing/infra/k8s/base/stack/elasticsearch.yaml @@ -4,7 +4,7 @@ metadata: name: elasticsearch spec: # TODO: replace with a pinned version such as 9.0.0-aaaaaaaa-SNAPSHOT - version: 9.0.0-3b9dafe0-SNAPSHOT + version: 9.0.0-faf48818-SNAPSHOT auth: fileRealm: - secretName: elasticsearch-admin diff --git a/testing/infra/k8s/base/stack/kibana.yaml b/testing/infra/k8s/base/stack/kibana.yaml index 6f431828faf..ca18661ffbf 100644 --- a/testing/infra/k8s/base/stack/kibana.yaml +++ b/testing/infra/k8s/base/stack/kibana.yaml @@ -4,7 +4,7 @@ metadata: name: kibana spec: # TODO: replace with a pinned version such as 9.0.0-aaaaaaaa-SNAPSHOT - version: 9.0.0-3b9dafe0-SNAPSHOT + version: 9.0.0-faf48818-SNAPSHOT count: 1 elasticsearchRef: name: elasticsearch diff --git a/testing/infra/terraform/modules/ec_deployment/README.md b/testing/infra/terraform/modules/ec_deployment/README.md index 84e228d1682..4b91fadc383 100644 --- a/testing/infra/terraform/modules/ec_deployment/README.md +++ b/testing/infra/terraform/modules/ec_deployment/README.md @@ -28,12 +28,12 @@ used to configure the module, please refer to the [EC Provider docs](https://reg | [ec_deployment.deployment](https://registry.terraform.io/providers/elastic/ec/0.5.1/docs/resources/deployment) | resource | | [local_file.custom_apm_integration_pkg](https://registry.terraform.io/providers/hashicorp/local/latest/docs/resources/file) | resource | | [local_file.drop_pipeline](https://registry.terraform.io/providers/hashicorp/local/latest/docs/resources/file) | resource | -| [local_file.enable_expvar](https://registry.terraform.io/providers/hashicorp/local/latest/docs/resources/file) | resource | +| [local_file.enable_features](https://registry.terraform.io/providers/hashicorp/local/latest/docs/resources/file) | resource | | [local_file.secret_token](https://registry.terraform.io/providers/hashicorp/local/latest/docs/resources/file) | resource | | [local_file.shard_settings](https://registry.terraform.io/providers/hashicorp/local/latest/docs/resources/file) | resource | | [null_resource.custom_apm_integration_pkg](https://registry.terraform.io/providers/hashicorp/null/latest/docs/resources/resource) | resource | | [null_resource.drop_pipeline](https://registry.terraform.io/providers/hashicorp/null/latest/docs/resources/resource) | resource | -| [null_resource.enable_expvar](https://registry.terraform.io/providers/hashicorp/null/latest/docs/resources/resource) | resource | +| [null_resource.enable_features](https://registry.terraform.io/providers/hashicorp/null/latest/docs/resources/resource) | resource | | [null_resource.secret_token](https://registry.terraform.io/providers/hashicorp/null/latest/docs/resources/resource) | resource | | [null_resource.shard_settings](https://registry.terraform.io/providers/hashicorp/null/latest/docs/resources/resource) | resource | | [ec_stack.deployment_version](https://registry.terraform.io/providers/elastic/ec/0.5.1/docs/data-sources/stack) | data source | @@ -47,12 +47,14 @@ used to configure the module, please refer to the [EC Provider docs](https://reg | [apm\_server\_expvar](#input\_apm\_server\_expvar) | Whether or not to enable APM Server's expvar endpoint. Defaults to false | `bool` | `false` | no | | [apm\_server\_pprof](#input\_apm\_server\_pprof) | Whether or not to enable APM Server's pprof endpoint. Defaults to false | `bool` | `false` | no | | [apm\_server\_size](#input\_apm\_server\_size) | Optional apm server instance size | `string` | `"1g"` | no | +| [apm\_server\_tail\_sampling](#input\_apm\_server\_tail\_sampling) | Whether or not to enable APM Server tail-based sampling. Defaults to false | `bool` | `false` | no | +| [apm\_server\_tail\_sampling\_storage\_limit](#input\_apm\_server\_tail\_sampling\_storage\_limit) | Storage size limit of APM Server tail-based sampling. Defaults to 10GB | `string` | `"10GB"` | no | | [apm\_server\_zone\_count](#input\_apm\_server\_zone\_count) | Optional apm server zone count | `number` | `1` | no | | [custom\_apm\_integration\_pkg\_path](#input\_custom\_apm\_integration\_pkg\_path) | Path to the zipped custom APM integration package, if empty custom apm integration pkg is not installed | `string` | `""` | no | | [deployment\_name\_prefix](#input\_deployment\_name\_prefix) | Optional ESS or ECE region. Defaults to GCP US West 2 (Los Angeles) | `string` | `"apmserver"` | no | -| [deployment\_template](#input\_deployment\_template) | Optional deployment template. Defaults to the CPU optimized template for GCP | `string` | `"gcp-compute-optimized-v3"` | no | -| [docker\_image](#input\_docker\_image) | Optional docker image overrides. The full map needs to be specified | `map(string)` |
{
"apm": "docker.elastic.co/cloud-release/elastic-agent-cloud",
"elasticsearch": "docker.elastic.co/cloud-release/elasticsearch-cloud-ess",
"kibana": "docker.elastic.co/cloud-release/kibana-cloud"
}
| no | -| [docker\_image\_tag\_override](#input\_docker\_image\_tag\_override) | Optional docker image tag overrides, The full map needs to be specified | `map(string)` |
{
"apm": "",
"elasticsearch": "",
"kibana": ""
}
| no | +| [deployment\_template](#input\_deployment\_template) | Optional deployment template. Defaults to the CPU optimized template for GCP | `string` | `"gcp-cpu-optimized"` | no | +| [docker\_image](#input\_docker\_image) | Optional docker image overrides. The full map needs to be specified | `map(string)` |
{
"apm": "docker.elastic.co/cloud-release/elastic-agent-cloud",
"elasticsearch": "docker.elastic.co/cloud-release/elasticsearch-cloud-ess",
"kibana": "docker.elastic.co/cloud-release/kibana-cloud"
}
| no | +| [docker\_image\_tag\_override](#input\_docker\_image\_tag\_override) | Optional docker image tag overrides, The full map needs to be specified | `map(string)` |
{
"apm": "",
"elasticsearch": "",
"kibana": ""
}
| no | | [drop\_pipeline](#input\_drop\_pipeline) | Whether or not to install an Elasticsearch ingest pipeline to drop all incoming APM documents. Defaults to false | `bool` | `false` | no | | [elasticsearch\_autoscale](#input\_elasticsearch\_autoscale) | Optional autoscale the Elasticsearch cluster | `bool` | `false` | no | | [elasticsearch\_dedicated\_masters](#input\_elasticsearch\_dedicated\_masters) | Optionally use dedicated masters for the Elasticsearch cluster | `bool` | `false` | no | diff --git a/testing/infra/terraform/modules/ec_deployment/deployment.tf b/testing/infra/terraform/modules/ec_deployment/deployment.tf index 808e2706285..0df75d7e077 100644 --- a/testing/infra/terraform/modules/ec_deployment/deployment.tf +++ b/testing/infra/terraform/modules/ec_deployment/deployment.tf @@ -113,21 +113,28 @@ resource "ec_deployment" "dedicated_observability_deployment" { kibana {} } -resource "local_file" "enable_expvar" { - content = templatefile("${path.module}/scripts/enable_expvar.tftpl", { - kibana_url = ec_deployment.deployment.kibana.0.https_endpoint, - elastic_password = ec_deployment.deployment.elasticsearch_password, - enable_expvar = var.apm_server_expvar - enable_pprof = var.apm_server_pprof +resource "local_file" "enable_features" { + content = templatefile("${path.module}/scripts/enable_features.tftpl", { + kibana_url = ec_deployment.deployment.kibana.0.https_endpoint, + elastic_password = ec_deployment.deployment.elasticsearch_password, + enable_expvar = var.apm_server_expvar + enable_pprof = var.apm_server_pprof + enable_tail_sampling = var.apm_server_tail_sampling + tail_sampling_storage_limit = var.apm_server_tail_sampling_storage_limit }) - filename = "${path.module}/scripts/enable_expvar.sh" + filename = "${path.module}/scripts/enable_features.sh" +} + +locals { + secret_token_file = "${path.cwd}/secret_token_value.json" } resource "local_file" "secret_token" { count = var.integrations_server ? 1 : 0 content = templatefile("${path.module}/scripts/secret_token.tftpl", { - kibana_url = ec_deployment.deployment.kibana.0.https_endpoint, - elastic_password = ec_deployment.deployment.elasticsearch_password, + kibana_url = ec_deployment.deployment.kibana.0.https_endpoint, + elastic_password = ec_deployment.deployment.elasticsearch_password, + secret_token_file = local.secret_token_file }) filename = "${path.module}/scripts/secret_token.sh" } @@ -153,13 +160,13 @@ resource "local_file" "custom_apm_integration_pkg" { filename = "${path.module}/scripts/custom-apm-integration-pkg.sh" } -resource "null_resource" "enable_expvar" { +resource "null_resource" "enable_features" { triggers = { - shell_hash = local_file.enable_expvar.id + shell_hash = local_file.enable_features.id integrations_server = var.integrations_server } provisioner "local-exec" { - command = "scripts/enable_expvar.sh" + command = "scripts/enable_features.sh" interpreter = ["/bin/bash", "-c"] working_dir = path.module } @@ -178,6 +185,16 @@ resource "null_resource" "secret_token" { } } +# Since the secret token value is set in the APM Integration policy, we need +# to extract it from there. +# Load it from secret_token_file as a sensitive variable. +data "local_sensitive_file" "secret_token" { + count = var.integrations_server ? 1 : 0 + + filename = local.secret_token_file + depends_on = [null_resource.secret_token] +} + resource "null_resource" "shard_settings" { count = var.apm_index_shards > 0 ? 1 : 0 triggers = { @@ -204,16 +221,6 @@ resource "null_resource" "custom_apm_integration_pkg" { } } -# Since the secret token value is set in the APM Integration policy, we need -# an "external" resource to run a shell script that returns the secret token -# as {"value":"SECRET_TOKEN"}. -data "external" "secret_token" { - count = var.integrations_server ? 1 : 0 - depends_on = [local_file.secret_token] - program = ["/bin/bash", "-c", "scripts/secret_token.sh"] - working_dir = path.module -} - resource "null_resource" "drop_pipeline" { count = var.drop_pipeline ? 1 : 0 triggers = { diff --git a/testing/infra/terraform/modules/ec_deployment/outputs.tf b/testing/infra/terraform/modules/ec_deployment/outputs.tf index 40ed6f409fa..865edcb4aa2 100644 --- a/testing/infra/terraform/modules/ec_deployment/outputs.tf +++ b/testing/infra/terraform/modules/ec_deployment/outputs.tf @@ -1,3 +1,8 @@ +output "deployment_id" { + value = ec_deployment.deployment.id + description = "The deployment ID for the created cluster" +} + output "kibana_url" { value = ec_deployment.deployment.kibana.0.https_endpoint description = "The secure Kibana URL" @@ -9,7 +14,7 @@ output "apm_url" { } output "apm_secret_token" { - value = var.integrations_server ? data.external.secret_token.0.result.value : ec_deployment.deployment.apm_secret_token + value = var.integrations_server ? chomp(data.local_sensitive_file.secret_token[0].content) : ec_deployment.deployment.apm_secret_token sensitive = true description = "The APM Secret token" } diff --git a/testing/infra/terraform/modules/ec_deployment/scripts/enable_expvar.tftpl b/testing/infra/terraform/modules/ec_deployment/scripts/enable_features.tftpl similarity index 57% rename from testing/infra/terraform/modules/ec_deployment/scripts/enable_expvar.tftpl rename to testing/infra/terraform/modules/ec_deployment/scripts/enable_features.tftpl index 0737afe7906..50bc102c7cf 100644 --- a/testing/infra/terraform/modules/ec_deployment/scripts/enable_expvar.tftpl +++ b/testing/infra/terraform/modules/ec_deployment/scripts/enable_features.tftpl @@ -14,21 +14,19 @@ if [[ "$${POLICY}" == *"$${NOT_FOUND_MSG}"* ]]; then exit 0 fi -echo $${POLICY} | grep '"expvar_enabled":{"type":"bool","value":true}' > /dev/null 2>&1 && EXPVAR_ENABLED=true -echo $${POLICY} | grep '"pprof_enabled":{"type":"bool","value":true}' > /dev/null 2>&1 && PPROF_ENABLED=true -if [[ $${EXPVAR_ENABLED} || $${PPROF_ENABLED} ]] ; then - echo "expvar or pprof already enabled" - exit 0 -fi - # Download and modify the APM policy echo $${POLICY} | jq '.item' | \ jq 'del(.id)' | jq 'del(.elasticsearch)'| jq 'del(.inputs[].compiled_input)' | jq 'del(.revision)' |\ jq 'del(.created_at)' | jq 'del(.created_by)' | jq 'del(.updated_at)' | jq 'del(.updated_by)' |\ jq 'select(.inputs[].policy_template == "apmserver").inputs[].vars.expvar_enabled = {type: "bool", value: ${enable_expvar}}' |\ - jq 'select(.inputs[].policy_template == "apmserver").inputs[].vars.pprof_enabled = {type: "bool", value: ${enable_pprof}}' > policy.json - -# Update the policy -curl -s -H 'content-type: application/json' -H 'kbn-xsrf: true' -X PUT -k -d@policy.json -u $${KIBANA_AUTH} $${KIBANA_ENDPOINT} + jq 'select(.inputs[].policy_template == "apmserver").inputs[].vars.pprof_enabled = {type: "bool", value: ${enable_pprof}}' |\ + jq 'select(.inputs[].policy_template == "apmserver").inputs[].vars.tail_sampling_storage_limit = {"value":"${tail_sampling_storage_limit}","type":"text"}' |\ + jq 'select(.inputs[].policy_template == "apmserver").inputs[].vars.tail_sampling_enabled = {type: "bool", value: ${enable_tail_sampling}}' > policy.json + +# Update the policy, hide output to prevent secret leakage. +if ! curl -s -o response.txt -H 'content-type: application/json' -H 'kbn-xsrf: true' -X PUT -k -d@policy.json -u $${KIBANA_AUTH} $${KIBANA_ENDPOINT}; then + # If command failed print output to aid troubleshooting. + cat response.txt +fi rm -f policy.json diff --git a/testing/infra/terraform/modules/ec_deployment/scripts/secret_token.tftpl b/testing/infra/terraform/modules/ec_deployment/scripts/secret_token.tftpl index 84555d11b33..ae850bb7ada 100644 --- a/testing/infra/terraform/modules/ec_deployment/scripts/secret_token.tftpl +++ b/testing/infra/terraform/modules/ec_deployment/scripts/secret_token.tftpl @@ -1,9 +1,12 @@ #!/bin/bash +# +# This script reads the APM Secret Token from the Elastic Agent policy and stores it +# in a local file to be used as Terraform output from this module. KIBANA_ENDPOINT=${kibana_url}/api/fleet/package_policies/elastic-cloud-apm KIBANA_AUTH=elastic:${elastic_password} -SECRET_TOKEN=$(curl -s -u $${KIBANA_AUTH} $${KIBANA_ENDPOINT} $${KIBANA_ENDPOINT} |\ - jq -r '.item | select(.inputs[].policy_template == "apmserver") .inputs[].vars.secret_token.value' | uniq) - -echo "{\"value\":\"$${SECRET_TOKEN}\"}" +curl -s -u $${KIBANA_AUTH} $${KIBANA_ENDPOINT} $${KIBANA_ENDPOINT} \ + | jq -r '.item | select(.inputs[].policy_template == "apmserver") .inputs[].vars.secret_token.value' \ + | uniq \ + > "${secret_token_file}" diff --git a/testing/infra/terraform/modules/ec_deployment/variables.tf b/testing/infra/terraform/modules/ec_deployment/variables.tf index 1a0f67932e7..8f6733b6544 100644 --- a/testing/infra/terraform/modules/ec_deployment/variables.tf +++ b/testing/infra/terraform/modules/ec_deployment/variables.tf @@ -13,7 +13,7 @@ variable "region" { } variable "deployment_template" { - default = "gcp-compute-optimized-v3" + default = "gcp-cpu-optimized" description = "Optional deployment template. Defaults to the CPU optimized template for GCP" type = string } @@ -108,7 +108,7 @@ variable "docker_image" { description = "Optional docker image overrides. The full map needs to be specified" } -# Enable APM Server's expvar +# Enable APM Server's features variable "apm_server_expvar" { default = false @@ -122,6 +122,18 @@ variable "apm_server_pprof" { type = bool } +variable "apm_server_tail_sampling" { + default = false + description = "Whether or not to enable APM Server tail-based sampling. Defaults to false" + type = bool +} + +variable "apm_server_tail_sampling_storage_limit" { + default = "10GB" + description = "Storage size limit of APM Server tail-based sampling. Defaults to 10GB" + type = string +} + variable "apm_index_shards" { default = 0 description = "The number of shards to set for APM Indices" diff --git a/testing/infra/terraform/modules/rally_workers/main.tf b/testing/infra/terraform/modules/rally_workers/main.tf index a61c7ee5e19..996c13de00b 100644 --- a/testing/infra/terraform/modules/rally_workers/main.tf +++ b/testing/infra/terraform/modules/rally_workers/main.tf @@ -1,6 +1,7 @@ provider "google" { - project = var.gcp_project - region = var.gcp_region + project = var.gcp_project + region = var.gcp_region + default_labels = module.tags } locals { diff --git a/testing/infra/terraform/modules/soaktest_workers/main.tf b/testing/infra/terraform/modules/soaktest_workers/main.tf index 00254f20cfb..e5af9451595 100644 --- a/testing/infra/terraform/modules/soaktest_workers/main.tf +++ b/testing/infra/terraform/modules/soaktest_workers/main.tf @@ -72,10 +72,6 @@ resource "google_compute_instance" "worker" { access_config {} } - labels = merge(module.tags.labels, { - workspace = terraform.workspace - }) - metadata = { ssh-keys = "${local.ssh_user_name}:${data.tls_public_key.worker_login.public_key_openssh}" } diff --git a/testing/infra/terraform/modules/soaktest_workers/provider.tf b/testing/infra/terraform/modules/soaktest_workers/provider.tf index f8d8d2a2f89..92f1b67e817 100644 --- a/testing/infra/terraform/modules/soaktest_workers/provider.tf +++ b/testing/infra/terraform/modules/soaktest_workers/provider.tf @@ -2,4 +2,8 @@ provider "google" { project = var.gcp_project region = var.gcp_region zone = var.gcp_zone + + default_labels = merge(module.tags.labels, { + workspace = terraform.workspace + }) } diff --git a/testing/infra/terraform/modules/standalone_apm_server/README.md b/testing/infra/terraform/modules/standalone_apm_server/README.md index 6b452b50cac..73c83cc7632 100644 --- a/testing/infra/terraform/modules/standalone_apm_server/README.md +++ b/testing/infra/terraform/modules/standalone_apm_server/README.md @@ -31,8 +31,12 @@ This module can be used to create a standalone APM Server deployment against a s | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| -| [apm\_instance\_type](#input\_apm\_instance\_type) | Optional apm server instance type overide | `string` | `""` | no | +| [apm\_instance\_type](#input\_apm\_instance\_type) | Optional apm server instance type override | `string` | `""` | no | | [apm\_server\_bin\_path](#input\_apm\_server\_bin\_path) | Optionally use the apm-server binary from the specified path instead | `string` | `""` | no | +| [apm\_server\_tail\_sampling](#input\_apm\_server\_tail\_sampling) | Whether or not to enable APM Server tail-based sampling. Defaults to false | `bool` | `false` | no | +| [apm\_server\_tail\_sampling\_storage\_limit](#input\_apm\_server\_tail\_sampling\_storage\_limit) | Storage size limit of APM Server tail-based sampling. Defaults to 10GB | `string` | `"10GB"` | no | +| [apm\_volume\_size](#input\_apm\_volume\_size) | Optional apm server volume size in GB override | `number` | `null` | no | +| [apm\_volume\_type](#input\_apm\_volume\_type) | Optional apm server volume type override | `string` | `null` | no | | [aws\_os](#input\_aws\_os) | Optional aws EC2 instance OS | `string` | `""` | no | | [aws\_provisioner\_key\_name](#input\_aws\_provisioner\_key\_name) | ssh key name to create the aws key pair and remote provision the EC2 instance | `string` | n/a | yes | | [ea\_managed](#input\_ea\_managed) | Whether or not install Elastic Agent managed APM Server | `bool` | `false` | no | @@ -40,7 +44,6 @@ This module can be used to create a standalone APM Server deployment against a s | [elasticsearch\_url](#input\_elasticsearch\_url) | The secure Elasticsearch URL | `string` | n/a | yes | | [elasticsearch\_username](#input\_elasticsearch\_username) | The Elasticsearch username | `string` | n/a | yes | | [stack\_version](#input\_stack\_version) | Optional stack version | `string` | `"latest"` | no | -| [tags](#input\_tags) | Optional set of tags to use for all deployments | `map(string)` | `{}` | no | | [vpc\_id](#input\_vpc\_id) | VPC ID to provision the EC2 instance | `string` | n/a | yes | ## Outputs diff --git a/testing/infra/terraform/modules/standalone_apm_server/apm-server.yml.tftpl b/testing/infra/terraform/modules/standalone_apm_server/apm-server.yml.tftpl index e51007ccf5a..20b1b27936a 100644 --- a/testing/infra/terraform/modules/standalone_apm_server/apm-server.yml.tftpl +++ b/testing/infra/terraform/modules/standalone_apm_server/apm-server.yml.tftpl @@ -10,7 +10,12 @@ apm-server: enabled: true pprof: enabled: true - + sampling: + tail: + enabled: ${apm_server_tail_sampling} + storage_limit: ${apm_server_tail_sampling_storage_limit} + policies: + - sample_rate: 0.1 output: elasticsearch: hosts: [ ${elasticsearch_url} ] diff --git a/testing/infra/terraform/modules/standalone_apm_server/elastic-agent.yml.tftpl b/testing/infra/terraform/modules/standalone_apm_server/elastic-agent.yml.tftpl index c9a6ac7aa32..dac0a7e0346 100644 --- a/testing/infra/terraform/modules/standalone_apm_server/elastic-agent.yml.tftpl +++ b/testing/infra/terraform/modules/standalone_apm_server/elastic-agent.yml.tftpl @@ -25,6 +25,12 @@ inputs: rum: enabled: true host: '0.0.0.0:${apm_port}' + sampling: + tail: + enabled: ${apm_server_tail_sampling} + storage_limit: ${apm_server_tail_sampling_storage_limit} + policies: + - sample_rate: 0.1 logging.level: debug logging.to_files: true logging.files: diff --git a/testing/infra/terraform/modules/standalone_apm_server/main.tf b/testing/infra/terraform/modules/standalone_apm_server/main.tf index e426fa0e5ce..86f08555be7 100644 --- a/testing/infra/terraform/modules/standalone_apm_server/main.tf +++ b/testing/infra/terraform/modules/standalone_apm_server/main.tf @@ -169,6 +169,11 @@ resource "aws_instance" "apm" { key_name = aws_key_pair.provisioner_key.key_name monitoring = false + root_block_device { + volume_type = var.apm_volume_type + volume_size = var.apm_volume_size + } + connection { type = "ssh" user = local.image_ssh_users[var.aws_os] @@ -185,12 +190,14 @@ resource "aws_instance" "apm" { provisioner "file" { destination = local.conf_path content = templatefile(var.ea_managed ? "${path.module}/elastic-agent.yml.tftpl" : "${path.module}/apm-server.yml.tftpl", { - elasticsearch_url = "${var.elasticsearch_url}", - elasticsearch_username = "${var.elasticsearch_username}", - elasticsearch_password = "${var.elasticsearch_password}", - apm_version = "${var.stack_version}" - apm_secret_token = "${random_password.apm_secret_token.result}" - apm_port = "${local.apm_port}" + elasticsearch_url = "${var.elasticsearch_url}", + elasticsearch_username = "${var.elasticsearch_username}", + elasticsearch_password = "${var.elasticsearch_password}", + apm_version = "${var.stack_version}" + apm_secret_token = "${random_password.apm_secret_token.result}" + apm_port = "${local.apm_port}" + apm_server_tail_sampling = "${var.apm_server_tail_sampling}" + apm_server_tail_sampling_storage_limit = "${var.apm_server_tail_sampling_storage_limit}" }) } diff --git a/testing/infra/terraform/modules/standalone_apm_server/variables.tf b/testing/infra/terraform/modules/standalone_apm_server/variables.tf index dbdf8dd7239..69c7a739bd0 100644 --- a/testing/infra/terraform/modules/standalone_apm_server/variables.tf +++ b/testing/infra/terraform/modules/standalone_apm_server/variables.tf @@ -7,7 +7,19 @@ variable "aws_os" { variable "apm_instance_type" { default = "" type = string - description = "Optional apm server instance type overide" + description = "Optional apm server instance type override" +} + +variable "apm_volume_type" { + default = null + type = string + description = "Optional apm server volume type override" +} + +variable "apm_volume_size" { + default = null + type = number + description = "Optional apm server volume size in GB override" } variable "vpc_id" { @@ -55,6 +67,18 @@ variable "apm_server_bin_path" { description = "Optionally use the apm-server binary from the specified path instead" } +variable "apm_server_tail_sampling" { + default = false + description = "Whether or not to enable APM Server tail-based sampling. Defaults to false" + type = bool +} + +variable "apm_server_tail_sampling_storage_limit" { + default = "10GB" + description = "Storage size limit of APM Server tail-based sampling. Defaults to 10GB" + type = string +} + variable "tags" { type = map(string) default = {} diff --git a/testing/infra/terraform/modules/tags/output.tf b/testing/infra/terraform/modules/tags/output.tf index 0731f8f9b96..55a86496622 100644 --- a/testing/infra/terraform/modules/tags/output.tf +++ b/testing/infra/terraform/modules/tags/output.tf @@ -2,10 +2,11 @@ locals { tags = { "division" : "engineering" "org" : "obs" - "team" : "apm-server" + "team" : "obs-ds-intake-services" "project" : var.project "build" : var.build "ephemeral" : "true" + "expiration_date" : formatdate("YYYY-MM-DD", timeadd(timestamp(), "24h")) } } diff --git a/testing/rally-cloud/variables.tf b/testing/rally-cloud/variables.tf index 49517b124d2..d0f1ab3c1bd 100644 --- a/testing/rally-cloud/variables.tf +++ b/testing/rally-cloud/variables.tf @@ -7,7 +7,7 @@ variable "ess_region" { variable "deployment_template" { type = string description = "Optional deployment template. Defaults to the CPU optimized template for GCP" - default = "gcp-compute-optimized-v3" + default = "gcp-cpu-optimized" } variable "stack_version" { diff --git a/testing/smoke/lib.sh b/testing/smoke/lib.sh old mode 100644 new mode 100755 diff --git a/testing/smoke/main.tf b/testing/smoke/main.tf index d7586f03d59..092e323e685 100644 --- a/testing/smoke/main.tf +++ b/testing/smoke/main.tf @@ -14,7 +14,7 @@ module "ec_deployment" { source = "../../infra/terraform/modules/ec_deployment" region = var.region - deployment_template = "gcp-compute-optimized-v3" + deployment_template = "gcp-cpu-optimized" deployment_name_prefix = "smoke-upgrade" apm_server_size = "1g" diff --git a/testing/smoke/os_matrix.sh b/testing/smoke/os_matrix.sh old mode 100644 new mode 100755 diff --git a/testing/smoke/test_supported_os.sh b/testing/smoke/test_supported_os.sh old mode 100644 new mode 100755 diff --git a/tools/go.mod b/tools/go.mod index 8b7a7226c63..e838f032902 100644 --- a/tools/go.mod +++ b/tools/go.mod @@ -7,7 +7,7 @@ require ( github.com/elastic/apm-tools v0.0.0-20230828065051-3f799314cc8b github.com/elastic/go-licenser v0.4.2 github.com/elastic/gobench v0.0.0-20220608141032-f30bc57e329c - github.com/goreleaser/nfpm/v2 v2.40.0 + github.com/goreleaser/nfpm/v2 v2.41.2 github.com/josephspurrier/goversioninfo v1.4.1 github.com/t-yuki/gocover-cobertura v0.0.0-20180217150009-aaee18c8195c github.com/terraform-docs/terraform-docs v0.19.0 @@ -20,7 +20,7 @@ require ( github.com/blang/semver v3.5.1+incompatible // indirect github.com/go-test/deep v1.0.4 // indirect github.com/kr/text v0.2.0 // indirect - github.com/rogpeppe/go-internal v1.11.0 // indirect + github.com/rogpeppe/go-internal v1.12.0 // indirect ) require ( @@ -28,10 +28,10 @@ require ( github.com/AlekSi/pointer v1.2.0 // indirect github.com/BurntSushi/toml v1.4.1-0.20240526193622-a339e1f7089c // indirect github.com/Masterminds/goutils v1.1.1 // indirect - github.com/Masterminds/semver/v3 v3.3.0 // indirect + github.com/Masterminds/semver/v3 v3.3.1 // indirect github.com/Masterminds/sprig/v3 v3.3.0 // indirect github.com/Microsoft/go-winio v0.6.1 // indirect - github.com/ProtonMail/go-crypto v1.0.0 // indirect + github.com/ProtonMail/go-crypto v1.1.4 // indirect github.com/ProtonMail/gopenpgp/v2 v2.7.4 // indirect github.com/agext/levenshtein v1.2.3 // indirect github.com/akavel/rsrc v0.10.2 // indirect @@ -40,11 +40,11 @@ require ( github.com/bitfield/gotestdox v0.2.2 // indirect github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb // indirect github.com/buger/jsonparser v1.1.1 // indirect - github.com/caarlos0/go-version v0.1.1 // indirect + github.com/caarlos0/go-version v0.2.0 // indirect github.com/cavaliergopher/cpio v1.0.1 // indirect github.com/cloudflare/circl v1.3.8 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.4 // indirect - github.com/cyphar/filepath-securejoin v0.2.5 // indirect + github.com/cyphar/filepath-securejoin v0.3.6 // indirect github.com/dnephin/pflag v1.0.7 // indirect github.com/elastic/elastic-transport-go/v8 v8.3.0 // indirect github.com/elastic/go-elasticsearch/v8 v8.8.1 // indirect @@ -52,8 +52,8 @@ require ( github.com/fatih/color v1.17.0 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect - github.com/go-git/go-billy/v5 v5.5.0 // indirect - github.com/go-git/go-git/v5 v5.12.0 // indirect + github.com/go-git/go-billy/v5 v5.6.1 // indirect + github.com/go-git/go-git/v5 v5.13.1 // indirect github.com/gobwas/glob v0.2.3 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.4 // indirect @@ -62,7 +62,7 @@ require ( github.com/google/rpmpack v0.6.1-0.20240329070804-c2247cbb881a // indirect github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect github.com/google/uuid v1.6.0 // indirect - github.com/goreleaser/chglog v0.6.1 // indirect + github.com/goreleaser/chglog v0.6.2 // indirect github.com/goreleaser/fileglob v1.3.0 // indirect github.com/hashicorp/go-hclog v1.6.3 // indirect github.com/hashicorp/go-plugin v1.6.1 // indirect @@ -73,10 +73,10 @@ require ( github.com/huandu/xstrings v1.5.0 // indirect github.com/iancoleman/orderedmap v0.3.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect - github.com/invopop/jsonschema v0.12.0 // indirect + github.com/invopop/jsonschema v0.13.0 // indirect github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect github.com/kevinburke/ssh_config v1.2.0 // indirect - github.com/klauspost/compress v1.17.10 // indirect + github.com/klauspost/compress v1.17.11 // indirect github.com/klauspost/pgzip v1.2.6 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/magiconair/properties v1.8.7 // indirect @@ -94,7 +94,6 @@ require ( github.com/muesli/mango-pflag v0.1.0 // indirect github.com/muesli/roff v0.1.0 // indirect github.com/oklog/run v1.1.0 // indirect - github.com/onsi/gomega v1.29.0 // indirect github.com/pelletier/go-toml/v2 v2.2.3 // indirect github.com/pjbgf/sha1cd v0.3.0 // indirect github.com/pkg/errors v0.9.1 // indirect @@ -103,7 +102,7 @@ require ( github.com/sagikazarmark/slog-shim v0.1.0 // indirect github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect github.com/shopspring/decimal v1.4.0 // indirect - github.com/skeema/knownhosts v1.2.2 // indirect + github.com/skeema/knownhosts v1.3.0 // indirect github.com/sourcegraph/conc v0.3.0 // indirect github.com/spf13/afero v1.11.0 // indirect github.com/spf13/cast v1.7.0 // indirect @@ -123,15 +122,15 @@ require ( gitlab.com/digitalxero/go-conventional-commit v1.0.7 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect - golang.org/x/crypto v0.27.0 // indirect + golang.org/x/crypto v0.31.0 // indirect golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 // indirect golang.org/x/exp/typeparams v0.0.0-20231108232855-2478ac86f678 // indirect golang.org/x/mod v0.21.0 // indirect - golang.org/x/net v0.29.0 // indirect - golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.25.0 // indirect - golang.org/x/term v0.24.0 // indirect - golang.org/x/text v0.18.0 // indirect + golang.org/x/net v0.33.0 // indirect + golang.org/x/sync v0.10.0 // indirect + golang.org/x/sys v0.28.0 // indirect + golang.org/x/term v0.27.0 // indirect + golang.org/x/text v0.21.0 // indirect golang.org/x/tools v0.25.0 // indirect golang.org/x/tools/go/vcs v0.1.0-deprecated // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 // indirect diff --git a/tools/go.sum b/tools/go.sum index 837f563f5b8..57283d13027 100644 --- a/tools/go.sum +++ b/tools/go.sum @@ -8,16 +8,16 @@ github.com/DataDog/zstd v1.5.5 h1:oWf5W7GtOLgp6bciQYDmhHHjdhYkALu6S/5Ni9ZgSvQ= github.com/DataDog/zstd v1.5.5/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= -github.com/Masterminds/semver/v3 v3.3.0 h1:B8LGeaivUe71a5qox1ICM/JLl0NqZSW5CHyL+hmvYS0= -github.com/Masterminds/semver/v3 v3.3.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= +github.com/Masterminds/semver/v3 v3.3.1 h1:QtNSWtVZ3nBfk8mAOu/B6v7FMJ+NHTIgUPi7rj+4nv4= +github.com/Masterminds/semver/v3 v3.3.1/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= github.com/Masterminds/sprig/v3 v3.3.0 h1:mQh0Yrg1XPo6vjYXgtf5OtijNAKJRNcTdOOGZe3tPhs= github.com/Masterminds/sprig/v3 v3.3.0/go.mod h1:Zy1iXRYNqNLUolqCpL4uhk6SHUMAOSCzdgBfDb35Lz0= github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= github.com/ProtonMail/go-crypto v0.0.0-20230717121422-5aa5874ade95/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0= -github.com/ProtonMail/go-crypto v1.0.0 h1:LRuvITjQWX+WIfr930YHG2HNfjR1uOfyf5vE0kC2U78= -github.com/ProtonMail/go-crypto v1.0.0/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0= +github.com/ProtonMail/go-crypto v1.1.4 h1:G5U5asvD5N/6/36oIw3k2bOfBn5XVcZrb7PBjzzKKoE= +github.com/ProtonMail/go-crypto v1.1.4/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE= github.com/ProtonMail/go-mime v0.0.0-20230322103455-7d82a3887f2f h1:tCbYj7/299ekTTXpdwKYF8eBlsYsDVoggDAuAjoK66k= github.com/ProtonMail/go-mime v0.0.0-20230322103455-7d82a3887f2f/go.mod h1:gcr0kNtGBqin9zDW9GOHcVntrwnjrK+qdJ06mWYBybw= github.com/ProtonMail/gopenpgp/v2 v2.7.4 h1:Vz/8+HViFFnf2A6XX8JOvZMrA6F5puwNvvF21O1mRlo= @@ -49,8 +49,8 @@ github.com/bufbuild/protocompile v0.4.0/go.mod h1:3v93+mbWn/v3xzN+31nwkJfrEpAUwp github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMUs= github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= -github.com/caarlos0/go-version v0.1.1 h1:1bikKHkGGVIIxqCmufhSSs3hpBScgHGacrvsi8FuIfc= -github.com/caarlos0/go-version v0.1.1/go.mod h1:Ze5Qx4TsBBi5FyrSKVg1Ibc44KGV/llAaKGp86oTwZ0= +github.com/caarlos0/go-version v0.2.0 h1:TTD5dF3PBAtRHbfCKRE173SrVVpbE0yX95EDQ4BwTGs= +github.com/caarlos0/go-version v0.2.0/go.mod h1:X+rI5VAtJDpcjCjeEIXpxGa5+rTcgur1FK66wS0/944= github.com/caarlos0/testfs v0.4.4 h1:3PHvzHi5Lt+g332CiShwS8ogTgS3HjrmzZxCm6JCDr8= github.com/caarlos0/testfs v0.4.4/go.mod h1:bRN55zgG4XCUVVHZCeU+/Tz1Q6AxEJOEJTliBy+1DMk= github.com/cavaliergopher/cpio v1.0.1 h1:KQFSeKmZhv0cr+kawA3a0xTQCU4QxXF1vhU7P7av2KM= @@ -61,8 +61,8 @@ github.com/cloudflare/circl v1.3.8/go.mod h1:PDRU+oXvdD7KCtgKxW95M5Z8BpSCJXQORiZ github.com/cpuguy83/go-md2man/v2 v2.0.4 h1:wfIWP927BUkWJb2NmU/kNDYIBTh/ziUX91+lVfRxZq4= github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/cyphar/filepath-securejoin v0.2.5 h1:6iR5tXJ/e6tJZzzdMc1km3Sa7RRIVBKAK32O2s7AYfo= -github.com/cyphar/filepath-securejoin v0.2.5/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= +github.com/cyphar/filepath-securejoin v0.3.6 h1:4d9N5ykBnSp5Xn2JkhocYDkOpURL/18CYMpo6xB9uWM= +github.com/cyphar/filepath-securejoin v0.3.6/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= @@ -81,8 +81,8 @@ github.com/elastic/go-licenser v0.4.2 h1:bPbGm8bUd8rxzSswFOqvQh1dAkKGkgAmrPxbUi+ github.com/elastic/go-licenser v0.4.2/go.mod h1:W8eH6FaZDR8fQGm+7FnVa7MxI1b/6dAqxz+zPB8nm5c= github.com/elastic/gobench v0.0.0-20220608141032-f30bc57e329c h1:XpeNAhmK96gUBNzLBwXsv7mioNlHtZr5dGaPwuEkN6U= github.com/elastic/gobench v0.0.0-20220608141032-f30bc57e329c/go.mod h1:dOGaaPOq2escJjXVSeyTxpJnOhLtpvaTc9C3LEHVMks= -github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a h1:mATvB/9r/3gvcejNsXKSkQ6lcIaNec2nyfOdlTBR2lU= -github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM= +github.com/elazarl/goproxy v1.2.3 h1:xwIyKHbaP5yfT6O9KIeYJR5549MXRQkoQMRXGztz8YQ= +github.com/elazarl/goproxy v1.2.3/go.mod h1:YfEbZtqP4AetfO6d40vWchF3znWX7C7Vd6ZMfdL8z64= github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= @@ -94,16 +94,16 @@ github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHk github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= -github.com/gliderlabs/ssh v0.3.7 h1:iV3Bqi942d9huXnzEF2Mt+CY9gLu8DNM4Obd+8bODRE= -github.com/gliderlabs/ssh v0.3.7/go.mod h1:zpHEXBstFnQYtGnB8k8kQLol82umzn/2/snG7alWVD8= +github.com/gliderlabs/ssh v0.3.8 h1:a4YXD1V7xMF9g5nTkdfnja3Sxy1PVDCj1Zg4Wb8vY6c= +github.com/gliderlabs/ssh v0.3.8/go.mod h1:xYoytBv1sV0aL3CavoDuJIQNURXkkfPA/wxQ1pL1fAU= github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI= github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic= -github.com/go-git/go-billy/v5 v5.5.0 h1:yEY4yhzCDuMGSv83oGxiBotRzhwhNr8VZyphhiu+mTU= -github.com/go-git/go-billy/v5 v5.5.0/go.mod h1:hmexnoNsr2SJU1Ju67OaNz5ASJY3+sHgFRpCtpDCKow= +github.com/go-git/go-billy/v5 v5.6.1 h1:u+dcrgaguSSkbjzHwelEjc0Yj300NUevrrPphk/SoRA= +github.com/go-git/go-billy/v5 v5.6.1/go.mod h1:0AsLr1z2+Uksi4NlElmMblP5rPcDZNRCD8ujZCRR2BE= github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4= github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII= -github.com/go-git/go-git/v5 v5.12.0 h1:7Md+ndsjrzZxbddRDZjF14qK+NN56sy6wkqaVrjZtys= -github.com/go-git/go-git/v5 v5.12.0/go.mod h1:FTM9VKtnI2m65hNI/TenDDDnUf2Q9FHnXYjuz9i5OEY= +github.com/go-git/go-git/v5 v5.13.1 h1:DAQ9APonnlvSWpvolXWIuV6Q6zXy2wHbN4cVlNR5Q+M= +github.com/go-git/go-git/v5 v5.13.1/go.mod h1:qryJB4cSBoq3FRoBRf5A77joojuBcmPJ0qu3XXXVixc= github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= github.com/go-test/deep v1.0.4 h1:u2CU3YKy9I2pmu9pX0eq50wCgjfGIt539SqR7FbHiho= github.com/go-test/deep v1.0.4/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= @@ -131,12 +131,12 @@ github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gopherjs/gopherjs v1.17.2 h1:fQnZVsXk8uxXIStYb0N4bGk7jeyTalG/wsZjQ25dO0g= github.com/gopherjs/gopherjs v1.17.2/go.mod h1:pRRIvn/QzFLrKfvEz3qUuEhtE/zLCWfreZ6J5gM2i+k= -github.com/goreleaser/chglog v0.6.1 h1:NZKiX8l0FTQPRzBgKST7knvNZmZ04f7PEGkN2wInfhE= -github.com/goreleaser/chglog v0.6.1/go.mod h1:Bnnfo07jMZkaAb0uRNASMZyOsX6ROW6X1qbXqN3guUo= +github.com/goreleaser/chglog v0.6.2 h1:qroqdMHzwoAPTHHzJtbCfYbwg/yWJrNQApZ6IQAq8bU= +github.com/goreleaser/chglog v0.6.2/go.mod h1:BP0xQQc6B8aM+4dhvSLlVTv0rvhuOF0JacDO1+h7L3U= github.com/goreleaser/fileglob v1.3.0 h1:/X6J7U8lbDpQtBvGcwwPS6OpzkNVlVEsFUVRx9+k+7I= github.com/goreleaser/fileglob v1.3.0/go.mod h1:Jx6BoXv3mbYkEzwm9THo7xbr5egkAraxkGorbJb4RxU= -github.com/goreleaser/nfpm/v2 v2.40.0 h1:M6WaaHeTCgNopUo9e8zgeHlOiN65LZAKqogzCJXBwYQ= -github.com/goreleaser/nfpm/v2 v2.40.0/go.mod h1:i9IfzvnHInDQohFs7iVHpWBoGaSDRp0+KG7KzNUXzns= +github.com/goreleaser/nfpm/v2 v2.41.2 h1:yOjpPlft5zpMPusbIWICphycIjE5orpY/IyMbkBbIJU= +github.com/goreleaser/nfpm/v2 v2.41.2/go.mod h1:zvk0z+wsPKe7Qdsp7z0ZJ9asnbwwhJUEsdOsPkgVC1E= github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k= github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= github.com/hashicorp/go-plugin v1.6.1 h1:P7MR2UP6gNKGPp+y7EZw2kOiq4IR9WiqLvp0XOsVdwI= @@ -159,8 +159,8 @@ github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -github.com/invopop/jsonschema v0.12.0 h1:6ovsNSuvn9wEQVOyc72aycBMVQFKz7cPdMJn10CvzRI= -github.com/invopop/jsonschema v0.12.0/go.mod h1:ffZ5Km5SWWRAIN6wbDXItl95euhFz2uON45H2qjYt+0= +github.com/invopop/jsonschema v0.13.0 h1:KvpoAJWEjR3uD9Kbm2HWJmqsEaHt8lBUpd0qHcIi21E= +github.com/invopop/jsonschema v0.13.0/go.mod h1:ffZ5Km5SWWRAIN6wbDXItl95euhFz2uON45H2qjYt+0= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= github.com/jhump/protoreflect v1.15.1 h1:HUMERORf3I3ZdX05WaQ6MIpd/NJ434hTp5YiKgfCL6c= @@ -172,8 +172,8 @@ github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7 github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4= github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= -github.com/klauspost/compress v1.17.10 h1:oXAz+Vh0PMUvJczoi+flxpnBEPxoER1IaAnU/NMPtT0= -github.com/klauspost/compress v1.17.10/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0= +github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc= +github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0= github.com/klauspost/pgzip v1.2.6 h1:8RXeL5crjEUFnR2/Sn6GJNWtSQ3Dk8pq4CL3jvdDyjU= github.com/klauspost/pgzip v1.2.6/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= @@ -226,8 +226,8 @@ github.com/muesli/roff v0.1.0 h1:YD0lalCotmYuF5HhZliKWlIx7IEhiXeSfq7hNjFqGF8= github.com/muesli/roff v0.1.0/go.mod h1:pjAHQM9hdUUwm/krAfrLGgJkXJ+YuhtsfZ42kieB2Ig= github.com/oklog/run v1.1.0 h1:GEenZ1cK0+q0+wsJew9qUg/DyD8k3JzYsZAi5gYi2mA= github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU= -github.com/onsi/gomega v1.29.0 h1:KIA/t2t5UBzoirT4H9tsML45GEbo3ouUnBHsCfD2tVg= -github.com/onsi/gomega v1.29.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ= +github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k= +github.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeDLwwY= github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M= github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc= github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4= @@ -239,8 +239,9 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= -github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= +github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= +github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/sagikazarmark/locafero v0.6.0 h1:ON7AQg37yzcRPU69mt7gwhFEBwxI6P9T4Qu3N51bwOk= @@ -256,8 +257,8 @@ github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k= github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/skeema/knownhosts v1.2.2 h1:Iug2P4fLmDw9f41PB6thxUkNUkJzB5i+1/exaj40L3A= -github.com/skeema/knownhosts v1.2.2/go.mod h1:xYbVRSPxqBZFrdmDyMmsOs+uX1UZC3nTN3ThzgDxUwo= +github.com/skeema/knownhosts v1.3.0 h1:AM+y0rI04VksttfwjkSTNQorvGqmwATnvnAHpSgc0LY= +github.com/skeema/knownhosts v1.3.0/go.mod h1:sPINvnADmT/qYH1kfv+ePMmOBTH6Tbl7b5LvTDjFK7M= github.com/smarty/assertions v1.15.0 h1:cR//PqUBUiQRakZWqBiFFQ9wb8emQGDb0HeGdqGByCY= github.com/smarty/assertions v1.15.0/go.mod h1:yABtdzeQs6l1brC900WlRNwj6ZR55d7B+E8C6HtKdec= github.com/smartystreets/goconvey v1.8.1 h1:qGjIddxOk4grTu9JPOU31tVfq3cNdBlNa5sSznIX1xY= @@ -283,8 +284,8 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= github.com/t-yuki/gocover-cobertura v0.0.0-20180217150009-aaee18c8195c h1:+aPplBwWcHBo6q9xrfWdMrT9o4kltkmmvpemgIjep/8= @@ -339,8 +340,8 @@ golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIi golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= -golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= -golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= +golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= +golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 h1:e66Fs6Z+fZTbFBAxKfP3PALWBtpfqks2bwGcexMxgtk= golang.org/x/exp v0.0.0-20240909161429-701f63a606c0/go.mod h1:2TbTHSBQa924w8M6Xs1QcRcFwyucIwBGpK1p2f1YFFY= golang.org/x/exp/typeparams v0.0.0-20231108232855-2478ac86f678 h1:1P7xPZEwZMoBoz0Yze5Nx2/4pxj6nw9ZqHWXqP0iRgQ= @@ -369,16 +370,16 @@ golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= -golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= -golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= +golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I= +golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= -golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= +golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502175342-a43fa875dd82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -408,8 +409,8 @@ golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= -golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -422,8 +423,8 @@ golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o= golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= -golang.org/x/term v0.24.0 h1:Mh5cbb+Zk2hqqXNO7S1iTjEphVL+jb8ZWaqh/g+JWkM= -golang.org/x/term v0.24.0/go.mod h1:lOBK/LVxemqiMij05LGJ0tzNr8xlmwBRJ81PX6wVLH8= +golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q= +golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= @@ -436,8 +437,8 @@ golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= -golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= diff --git a/x-pack/apm-server/aggregation.go b/x-pack/apm-server/aggregation.go index 856d4d7449b..f9d4e29654a 100644 --- a/x-pack/apm-server/aggregation.go +++ b/x-pack/apm-server/aggregation.go @@ -11,9 +11,7 @@ import ( "github.com/elastic/apm-server/x-pack/apm-server/aggregation" ) -func newAggregationProcessors(args beater.ServerParams) ([]namedProcessor, error) { - var processors []namedProcessor - +func newAggregationProcessor(args beater.ServerParams) (namedProcessor, error) { name := "LSM aggregator" agg, err := aggregation.New( args.Config.Aggregation.MaxServices, @@ -24,9 +22,7 @@ func newAggregationProcessors(args beater.ServerParams) ([]namedProcessor, error args.Logger, ) if err != nil { - return nil, errors.Wrapf(err, "error creating %s", name) + return namedProcessor{}, errors.Wrapf(err, "error creating %s", name) } - processors = append(processors, namedProcessor{name: name, processor: agg}) - - return processors, nil + return namedProcessor{name: name, processor: agg}, nil } diff --git a/x-pack/apm-server/default.pgo b/x-pack/apm-server/default.pgo index d377661ceed..1d1e3b98c8d 100644 Binary files a/x-pack/apm-server/default.pgo and b/x-pack/apm-server/default.pgo differ diff --git a/x-pack/apm-server/main.go b/x-pack/apm-server/main.go index 893681c966a..3ffb9dc6757 100644 --- a/x-pack/apm-server/main.go +++ b/x-pack/apm-server/main.go @@ -11,8 +11,8 @@ import ( "os" "sync" - "github.com/dgraph-io/badger/v2" - "github.com/gofrs/uuid" + "github.com/gofrs/uuid/v5" + "go.opentelemetry.io/otel/metric" "golang.org/x/sync/errgroup" "github.com/elastic/beats/v7/libbeat/common/reload" @@ -21,7 +21,6 @@ import ( "github.com/elastic/elastic-agent-client/v7/pkg/proto" "github.com/elastic/elastic-agent-libs/config" "github.com/elastic/elastic-agent-libs/logp" - "github.com/elastic/elastic-agent-libs/monitoring" "github.com/elastic/elastic-agent-libs/paths" "github.com/elastic/apm-data/model/modelpb" @@ -37,16 +36,9 @@ const ( ) var ( - // Note: this registry is created in github.com/elastic/apm-server/sampling. That package - // will hopefully disappear in the future, when agents no longer send unsampled transactions. - samplingMonitoringRegistry = monitoring.Default.GetRegistry("apm-server.sampling") - - // badgerDB holds the badger database to use when tail-based sampling is configured. - badgerMu sync.Mutex - badgerDB *badger.DB - - storageMu sync.Mutex - storage *eventstorage.ShardedReadWriter + // db holds the database to use when tail-based sampling is configured. + dbMu sync.Mutex + db *eventstorage.StorageManager // samplerUUID is a UUID used to identify sampled trace ID documents // published by this process. @@ -91,11 +83,11 @@ type processor interface { func newProcessors(args beater.ServerParams) ([]namedProcessor, error) { var processors []namedProcessor - aggregationProcessors, err := newAggregationProcessors(args) + aggregationProcessor, err := newAggregationProcessor(args) if err != nil { return nil, err } - processors = append(processors, aggregationProcessors...) + processors = append(processors, aggregationProcessor) if args.Config.Sampling.Tail.Enabled { const name = "tail sampler" @@ -103,8 +95,6 @@ func newProcessors(args beater.ServerParams) ([]namedProcessor, error) { if err != nil { return nil, fmt.Errorf("error creating %s: %w", name, err) } - samplingMonitoringRegistry.Remove("tail") - monitoring.NewFunc(samplingMonitoringRegistry, "tail", sampler.CollectMonitoring, monitoring.Report) processors = append(processors, namedProcessor{name: name, processor: sampler}) } return processors, nil @@ -118,11 +108,10 @@ func newTailSamplingProcessor(args beater.ServerParams) (*sampling.Processor, er } storageDir := paths.Resolve(paths.Data, tailSamplingStorageDir) - badgerDB, err = getBadgerDB(storageDir) + db, err := getDB(storageDir, args.MeterProvider) if err != nil { - return nil, fmt.Errorf("failed to get Badger database: %w", err) + return nil, fmt.Errorf("failed to get tail-sampling database: %w", err) } - readWriters := getStorage(badgerDB) policies := make([]sampling.Policy, len(tailSamplingConfig.Policies)) for i, in := range tailSamplingConfig.Policies { @@ -139,6 +128,7 @@ func newTailSamplingProcessor(args beater.ServerParams) (*sampling.Processor, er return sampling.NewProcessor(sampling.Config{ BatchProcessor: args.BatchProcessor, + MeterProvider: args.MeterProvider, LocalSamplingConfig: sampling.LocalSamplingConfig{ FlushInterval: tailSamplingConfig.Interval, MaxDynamicServices: 1000, @@ -156,37 +146,30 @@ func newTailSamplingProcessor(args beater.ServerParams) (*sampling.Processor, er UUID: samplerUUID.String(), }, StorageConfig: sampling.StorageConfig{ - DB: badgerDB, - Storage: readWriters, - StorageDir: storageDir, - StorageGCInterval: tailSamplingConfig.StorageGCInterval, - StorageLimit: tailSamplingConfig.StorageLimitParsed, - TTL: tailSamplingConfig.TTL, + DB: db, + Storage: db.NewReadWriter(), + StorageLimit: tailSamplingConfig.StorageLimitParsed, + TTL: tailSamplingConfig.TTL, + DiscardOnWriteFailure: tailSamplingConfig.DiscardOnWriteFailure, }, }) } -func getBadgerDB(storageDir string) (*badger.DB, error) { - badgerMu.Lock() - defer badgerMu.Unlock() - if badgerDB == nil { - db, err := eventstorage.OpenBadger(storageDir, -1) +func getDB(storageDir string, mp metric.MeterProvider) (*eventstorage.StorageManager, error) { + dbMu.Lock() + defer dbMu.Unlock() + if db == nil { + var opts []eventstorage.StorageManagerOptions + if mp != nil { + opts = append(opts, eventstorage.WithMeterProvider(mp)) + } + sm, err := eventstorage.NewStorageManager(storageDir, opts...) if err != nil { return nil, err } - badgerDB = db - } - return badgerDB, nil -} - -func getStorage(db *badger.DB) *eventstorage.ShardedReadWriter { - storageMu.Lock() - defer storageMu.Unlock() - if storage == nil { - eventCodec := eventstorage.ProtobufCodec{} - storage = eventstorage.New(db, eventCodec).NewShardedReadWriter() + db = sm } - return storage + return db, nil } // runServerWithProcessors runs the APM Server and the given list of processors. @@ -250,28 +233,21 @@ func wrapServer(args beater.ServerParams, runServer beater.RunServerFunc) (beate return args, wrappedRunServer, nil } -// closeBadger is called at process exit time to close the badger.DB opened +// closeDB is called at process exit time to close the StorageManager opened // by the tail-based sampling processor constructor, if any. This is never -// called concurrently with opening badger.DB/accessing the badgerDB global, -// so it does not need to hold badgerMu. -func closeBadger() error { - if badgerDB != nil { - return badgerDB.Close() +// called concurrently with opening DB/accessing the db global, +// so it does not need to hold dbMu. +func closeDB() error { + if db != nil { + err := db.Close() + db = nil + return err } return nil } -func closeStorage() { - if storage != nil { - storage.Close() - } -} - func cleanup() error { - // Close the underlying storage, the storage will be flushed on processor stop. - closeStorage() - - return closeBadger() + return closeDB() } func Main() error { @@ -281,6 +257,9 @@ func Main() error { Config: args.Config, Logger: args.Logger, WrapServer: wrapServer, + + MeterProvider: args.MeterProvider, + MetricsGatherer: args.MetricsGatherer, }) }, ) diff --git a/x-pack/apm-server/main_test.go b/x-pack/apm-server/main_test.go index fad69edc008..ff8de5e4969 100644 --- a/x-pack/apm-server/main_test.go +++ b/x-pack/apm-server/main_test.go @@ -14,26 +14,24 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "go.elastic.co/apm/v2/apmtest" + sdkmetric "go.opentelemetry.io/otel/sdk/metric" + "go.opentelemetry.io/otel/sdk/metric/metricdata" "github.com/elastic/apm-data/model/modelpb" "github.com/elastic/elastic-agent-libs/logp" - "github.com/elastic/elastic-agent-libs/monitoring" "github.com/elastic/elastic-agent-libs/paths" "github.com/elastic/apm-server/internal/beater" "github.com/elastic/apm-server/internal/beater/config" + "github.com/elastic/apm-server/internal/beater/monitoringtest" "github.com/elastic/apm-server/internal/elasticsearch" ) func TestMonitoring(t *testing.T) { - // samplingMonitoringRegistry will be nil, as under normal circumstances - // we rely on apm-server/sampling to create the registry. - samplingMonitoringRegistry = monitoring.NewRegistry() - home := t.TempDir() err := paths.InitPaths(&paths.Path{Home: home}) require.NoError(t, err) - defer closeBadger() // close badger.DB so data dir can be deleted on Windows + defer closeDB() // close DB so data dir can be deleted on Windows cfg := config.DefaultConfig() cfg.Sampling.Tail.Enabled = true @@ -45,25 +43,34 @@ func TestMonitoring(t *testing.T) { cfg.Aggregation.ServiceTransactions.MaxGroups = 10000 cfg.Aggregation.ServiceDestinations.MaxGroups = 10000 + reader := sdkmetric.NewManualReader(sdkmetric.WithTemporalitySelector( + func(ik sdkmetric.InstrumentKind) metricdata.Temporality { + return metricdata.DeltaTemporality + }, + )) + mp := sdkmetric.NewMeterProvider(sdkmetric.WithReader(reader)) + // Wrap & run the server twice, to ensure metric registration does not panic. runServerError := errors.New("runServer") for i := 0; i < 2; i++ { - var tailSamplingMonitoringSnapshot monitoring.FlatSnapshot serverParams, runServer, err := wrapServer(beater.ServerParams{ Config: cfg, Logger: logp.NewLogger(""), Tracer: apmtest.DiscardTracer, + MeterProvider: mp, BatchProcessor: modelpb.ProcessBatchFunc(func(ctx context.Context, b *modelpb.Batch) error { return nil }), Namespace: "default", NewElasticsearchClient: elasticsearch.NewClient, }, func(ctx context.Context, args beater.ServerParams) error { - tailSamplingMonitoringSnapshot = monitoring.CollectFlatSnapshot(samplingMonitoringRegistry, monitoring.Full, false) return runServerError }) require.NoError(t, err) err = runServer(context.Background(), serverParams) assert.Equal(t, runServerError, err) - assert.NotEqual(t, monitoring.MakeFlatSnapshot(), tailSamplingMonitoringSnapshot) + monitoringtest.ExpectContainOtelMetricsKeys(t, reader, []string{ + "apm-server.sampling.tail.storage.lsm_size", + "apm-server.sampling.tail.storage.value_log_size", + }) } } diff --git a/x-pack/apm-server/root_test.go b/x-pack/apm-server/root_test.go index 39fbf2aa30d..9be226c59b0 100644 --- a/x-pack/apm-server/root_test.go +++ b/x-pack/apm-server/root_test.go @@ -22,7 +22,6 @@ func TestSubCommands(t *testing.T) { } assert.ElementsMatch(t, []string{ - "apikey", "export", "keystore", "run", diff --git a/x-pack/apm-server/sampling/config.go b/x-pack/apm-server/sampling/config.go index 43d5c34d96e..41d85265690 100644 --- a/x-pack/apm-server/sampling/config.go +++ b/x-pack/apm-server/sampling/config.go @@ -7,8 +7,8 @@ package sampling import ( "time" - "github.com/dgraph-io/badger/v2" "github.com/pkg/errors" + "go.opentelemetry.io/otel/metric" "github.com/elastic/apm-data/model/modelpb" "github.com/elastic/apm-server/x-pack/apm-server/sampling/eventstorage" @@ -22,6 +22,10 @@ type Config struct { // tail-sampled trace events. BatchProcessor modelpb.BatchProcessor + // MeterProvider holds a metric.MeterProvider that can be used for + // creating metrics. + MeterProvider metric.MeterProvider + LocalSamplingConfig RemoteSamplingConfig StorageConfig @@ -96,29 +100,25 @@ type DataStreamConfig struct { // StorageConfig holds Processor configuration related to event storage. type StorageConfig struct { - // DB holds the badger database in which event storage will be maintained. + // DB holds the StorageManager in which event storage will be maintained. // // DB will not be closed when the processor is closed. - DB *badger.DB - - // Storage holds the read writers which provide sharded, locked access to storage. - // - // Storage lives outside processor lifecycle and will not be closed when processor - // is closed - Storage *eventstorage.ShardedReadWriter - - // StorageDir holds the directory in which event storage will be maintained. - StorageDir string + DB *eventstorage.StorageManager - // StorageGCInterval holds the amount of time between storage garbage collections. - StorageGCInterval time.Duration + // Storage is the read writer to DB. + Storage eventstorage.RW - // StorageLimit for the badger database, in bytes. + // StorageLimit for the TBS database, in bytes. StorageLimit uint64 // TTL holds the amount of time before events and sampling decisions // are expired from local storage. TTL time.Duration + + // DiscardOnWriteFailure defines indexing behavior when event storage write fails, e.g. when storage limit is reached. + // When set to false, TBS indexes all traces, and may significantly increase indexing load. + // When set to true, there will be data loss, resulting in broken traces. + DiscardOnWriteFailure bool } // Policy holds a tail-sampling policy: criteria for matching root transactions, @@ -238,15 +238,6 @@ func (config StorageConfig) validate() error { if config.DB == nil { return errors.New("DB unspecified") } - if config.Storage == nil { - return errors.New("Storage unspecified") - } - if config.StorageDir == "" { - return errors.New("StorageDir unspecified") - } - if config.StorageGCInterval <= 0 { - return errors.New("StorageGCInterval unspecified or negative") - } if config.TTL <= 0 { return errors.New("TTL unspecified or negative") } diff --git a/x-pack/apm-server/sampling/config_test.go b/x-pack/apm-server/sampling/config_test.go index f926711be7d..b5575a939b3 100644 --- a/x-pack/apm-server/sampling/config_test.go +++ b/x-pack/apm-server/sampling/config_test.go @@ -7,7 +7,6 @@ package sampling_test import ( "testing" - "github.com/dgraph-io/badger/v2" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -72,16 +71,7 @@ func TestNewProcessorConfigInvalid(t *testing.T) { config.UUID = "server" assertInvalidConfigError("invalid storage config: DB unspecified") - config.DB = &badger.DB{} - - assertInvalidConfigError("invalid storage config: Storage unspecified") - config.Storage = &eventstorage.ShardedReadWriter{} - - assertInvalidConfigError("invalid storage config: StorageDir unspecified") - config.StorageDir = "tbs" - - assertInvalidConfigError("invalid storage config: StorageGCInterval unspecified or negative") - config.StorageGCInterval = 1 + config.DB = &eventstorage.StorageManager{} assertInvalidConfigError("invalid storage config: TTL unspecified or negative") config.TTL = 1 diff --git a/x-pack/apm-server/sampling/eventstorage/badger.go b/x-pack/apm-server/sampling/eventstorage/badger.go deleted file mode 100644 index 99219262d4f..00000000000 --- a/x-pack/apm-server/sampling/eventstorage/badger.go +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one -// or more contributor license agreements. Licensed under the Elastic License 2.0; -// you may not use this file except in compliance with the Elastic License 2.0. - -package eventstorage - -import ( - "github.com/dgraph-io/badger/v2" - - "github.com/elastic/apm-server/internal/logs" - "github.com/elastic/elastic-agent-libs/logp" -) - -const ( - defaultValueLogFileSize = 64 * 1024 * 1024 -) - -// OpenBadger creates or opens a Badger database with the specified location -// and value log file size. If the value log file size is <= 0, the default -// of 64MB will be used. -// -// NOTE(axw) only one badger.DB for a given storage directory may be open at any given time. -func OpenBadger(storageDir string, valueLogFileSize int64) (*badger.DB, error) { - logger := logp.NewLogger(logs.Sampling) - // Tunable memory options: - // - NumMemtables - default 5 in-mem tables (MaxTableSize default) - // - NumLevelZeroTables - default 5 - number of L0 tables before compaction starts. - // - NumLevelZeroTablesStall - number of L0 tables before writing stalls (waiting for compaction). - // - IndexCacheSize - default all in mem, Each table has its own bloom filter and each bloom filter is approximately of 5 MB. - // - MaxTableSize - Default 64MB - if valueLogFileSize <= 0 { - valueLogFileSize = defaultValueLogFileSize - } - const tableLimit = 4 - badgerOpts := badger.DefaultOptions(storageDir). - WithLogger(&LogpAdaptor{Logger: logger}). - WithTruncate(true). // Truncate unreadable files which cannot be read. - WithNumMemtables(tableLimit). // in-memory tables. - WithNumLevelZeroTables(tableLimit). // L0 tables. - WithNumLevelZeroTablesStall(tableLimit * 3). // Maintain the default 1-to-3 ratio before stalling. - WithMaxTableSize(int64(16 << 20)). // Max LSM table or file size. - WithValueLogFileSize(valueLogFileSize) // vlog file size. - - return badger.Open(badgerOpts) -} diff --git a/x-pack/apm-server/sampling/eventstorage/doc.go b/x-pack/apm-server/sampling/eventstorage/doc.go new file mode 100644 index 00000000000..4bd93791b94 --- /dev/null +++ b/x-pack/apm-server/sampling/eventstorage/doc.go @@ -0,0 +1,14 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License 2.0; +// you may not use this file except in compliance with the Elastic License 2.0. + +// Package eventstorage implements the storage layer for tail-based sampling event +// and sampling decision read-writes. +// +// The database of choice is Pebble, which does not have TTL handling built-in, +// and we implement our own TTL handling on top of the database: +// - TTL is divided up into N parts, where N is partitionsPerTTL. +// - A database holds N + 1 + 1 partitions. +// - Every TTL/N we will discard the oldest partition, so we keep a rolling window of N+1 partitions. +// - Writes will go to the most recent partition, and we'll read across N+1 partitions +package eventstorage diff --git a/x-pack/apm-server/sampling/eventstorage/logger.go b/x-pack/apm-server/sampling/eventstorage/logger.go deleted file mode 100644 index 695a68e8a78..00000000000 --- a/x-pack/apm-server/sampling/eventstorage/logger.go +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one -// or more contributor license agreements. Licensed under the Elastic License 2.0; -// you may not use this file except in compliance with the Elastic License 2.0. - -package eventstorage - -import ( - "fmt" - "sync" - - "github.com/elastic/elastic-agent-libs/logp" -) - -// LogpAdaptor adapts logp.Logger to the badger.Logger interface. -type LogpAdaptor struct { - *logp.Logger - - mu sync.RWMutex - last string -} - -// Errorf prints the log message when the current message isn't the same as the -// previously logged message. -func (a *LogpAdaptor) Errorf(format string, args ...interface{}) { - msg := fmt.Sprintf(format, args...) - if a.setLast(msg) { - a.Logger.Errorf(format, args...) - } -} - -func (a *LogpAdaptor) setLast(msg string) bool { - a.mu.RLock() - if msg != a.last { - a.mu.RUnlock() - return false - } - a.mu.RUnlock() - a.mu.Lock() - defer a.mu.Unlock() - shouldSet := msg != a.last - if shouldSet { - a.last = msg - } - return shouldSet -} - -// Warningf adapts badger.Logger.Warningf to logp.Logger.Warngf. -func (a *LogpAdaptor) Warningf(format string, args ...interface{}) { - a.Warnf(format, args...) -} diff --git a/x-pack/apm-server/sampling/eventstorage/partition_rw.go b/x-pack/apm-server/sampling/eventstorage/partition_rw.go new file mode 100644 index 00000000000..c051e5ce069 --- /dev/null +++ b/x-pack/apm-server/sampling/eventstorage/partition_rw.go @@ -0,0 +1,80 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License 2.0; +// you may not use this file except in compliance with the Elastic License 2.0. + +package eventstorage + +import ( + "errors" + + "github.com/elastic/apm-data/model/modelpb" +) + +// PartitionReadWriter reads from and writes to storage across partitions. +type PartitionReadWriter struct { + s *Storage +} + +// WriteTraceSampled records the tail-sampling decision for the given trace ID. +func (rw *PartitionReadWriter) WriteTraceSampled(traceID string, sampled bool) (err error) { + rw.s.partitioner.CurrentIDFunc(func(pid int) { + err = NewPrefixReadWriter(rw.s.db, byte(pid), rw.s.codec).WriteTraceSampled(traceID, sampled) + }) + return +} + +// IsTraceSampled reports whether traceID belongs to a trace that is sampled +// or unsampled. If no sampling decision has been recorded, IsTraceSampled +// returns ErrNotFound. +// +// The performance of IsTraceSampled is crucial since it is in the hot path. +// It is called +// 1. when a remote sampling decision is received from pubsub +// 2. (hot path) when a transaction / span comes in, check if a sampling decision has already been made +func (rw *PartitionReadWriter) IsTraceSampled(traceID string) (bool, error) { + var errs []error + for pid := range rw.s.partitioner.ActiveIDs() { + sampled, err := NewPrefixReadWriter(rw.s.db, byte(pid), rw.s.codec).IsTraceSampled(traceID) + if err == nil { + return sampled, nil + } else if err != ErrNotFound { + errs = append(errs, err) + } + } + if len(errs) > 0 { + return false, errors.Join(errs...) + } + return false, ErrNotFound +} + +// WriteTraceEvent writes a trace event to storage. +func (rw *PartitionReadWriter) WriteTraceEvent(traceID, id string, event *modelpb.APMEvent) (err error) { + rw.s.partitioner.CurrentIDFunc(func(pid int) { + err = NewPrefixReadWriter(rw.s.db, byte(pid), rw.s.codec).WriteTraceEvent(traceID, id, event) + }) + return +} + +// DeleteTraceEvent deletes the trace event from storage. +func (rw *PartitionReadWriter) DeleteTraceEvent(traceID, id string) error { + var errs []error + for pid := range rw.s.partitioner.ActiveIDs() { + err := NewPrefixReadWriter(rw.s.db, byte(pid), rw.s.codec).DeleteTraceEvent(traceID, id) + if err != nil { + errs = append(errs, err) + } + } + return errors.Join(errs...) +} + +// ReadTraceEvents reads trace events with the given trace ID from storage into out. +func (rw *PartitionReadWriter) ReadTraceEvents(traceID string, out *modelpb.Batch) error { + var errs []error + for pid := range rw.s.partitioner.ActiveIDs() { + err := NewPrefixReadWriter(rw.s.db, byte(pid), rw.s.codec).ReadTraceEvents(traceID, out) + if err != nil { + errs = append(errs, err) + } + } + return errors.Join(errs...) +} diff --git a/x-pack/apm-server/sampling/eventstorage/partitioner.go b/x-pack/apm-server/sampling/eventstorage/partitioner.go new file mode 100644 index 00000000000..512a4de1226 --- /dev/null +++ b/x-pack/apm-server/sampling/eventstorage/partitioner.go @@ -0,0 +1,91 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License 2.0; +// you may not use this file except in compliance with the Elastic License 2.0. + +package eventstorage + +import ( + "iter" + "sync" +) + +const ( + // maxTotalPartitions is the maximum number of total partitions. + // It is used for a sanity check specific to how we use it as a byte prefix in database keys. + // It MUST be less than 256 to be contained in a byte. + // It has additional (arbitrary) limitations: + // - MUST be less than reservedKeyPrefix to avoid accidentally overwriting reserved keys down the line. + // - MUST be less than traceIDSeparator to avoid being misinterpreted as the separator during pebble internal key comparisons + maxTotalPartitions = int(min(reservedKeyPrefix, traceIDSeparator)) - 1 +) + +// Partitioner is a partitioned ring with `total` number of partitions. +// 1 of them is inactive while all the others are active. +// `current` points at the rightmost active partition. +// +// Example for total=4: +// (A: active, I: inactive, ^ points at the current active entry) +// A-I-A-A +// ^...... +// current +type Partitioner struct { + total int // length of the ring + current int + mu sync.RWMutex +} + +// NewPartitioner returns a partitioner with `actives` number of active partitions. +func NewPartitioner(actives, currentID int) *Partitioner { + total := actives + 1 // actives + 1 inactive + if total >= maxTotalPartitions { + panic("too many partitions") + } + return &Partitioner{total: total, current: currentID} +} + +// Rotate rotates partitions to the right by 1 position and +// returns the ID of the new current active entry. +// +// Example for total=4: +// (A: active, I: inactive, ^ points at the current active entry) +// A-I-A-A +// ^...... +// +// After Rotate: +// A-A-I-A +// ..^.... +func (p *Partitioner) Rotate() (newCurrent, newInactive int) { + p.mu.Lock() + defer p.mu.Unlock() + p.current = (p.current + 1) % p.total + return p.current, (p.current + 1) % p.total +} + +// ActiveIDs returns an iterator containing all active partitions. +// It contains total - 1 partitions. +// +// As ActiveIDs holds RLock internally, +// - Rotate should never be called within ActiveIDs +// - the returned partition IDs may be outdated if used outside `range` +func (p *Partitioner) ActiveIDs() iter.Seq[int] { + return func(yield func(int) bool) { + p.mu.RLock() + defer p.mu.RUnlock() + for i := 0; i < p.total-1; i++ { + if !yield((p.current + p.total - i) % p.total) { + return + } + } + } +} + +// CurrentIDFunc calls function f which accepts the ID of the current partition (rightmost active). +// +// As CurrentIDFunc holds RLock internally, +// - Rotate should never be called within CurrentIDFunc +// - the returned partition ID may be outdated if used outside f +func (p *Partitioner) CurrentIDFunc(f func(int)) { + p.mu.RLock() + defer p.mu.RUnlock() + f(p.current) +} diff --git a/x-pack/apm-server/sampling/eventstorage/partitioner_test.go b/x-pack/apm-server/sampling/eventstorage/partitioner_test.go new file mode 100644 index 00000000000..4715ed2c2d9 --- /dev/null +++ b/x-pack/apm-server/sampling/eventstorage/partitioner_test.go @@ -0,0 +1,104 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License 2.0; +// you may not use this file except in compliance with the Elastic License 2.0. + +package eventstorage + +import ( + "slices" + "sync" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestPartitioner(t *testing.T) { + p := NewPartitioner(2, 0) // partition id 0, 1, 2 + + p.CurrentIDFunc(func(pid int) { + assert.Equal(t, 0, pid) + }) + assert.Equal(t, []int{0, 2}, slices.Collect(p.ActiveIDs())) + + // 0 -> 1 + newCurrent, newInactive := p.Rotate() + + assert.Equal(t, 1, newCurrent) + p.CurrentIDFunc(func(pid int) { + assert.Equal(t, 1, pid) + }) + assert.Equal(t, 2, newInactive) + assert.Equal(t, []int{1, 0}, slices.Collect(p.ActiveIDs())) + + // 1 -> 2 + newCurrent, newInactive = p.Rotate() + + assert.Equal(t, 2, newCurrent) + p.CurrentIDFunc(func(pid int) { + assert.Equal(t, 2, pid) + }) + assert.Equal(t, 0, newInactive) + assert.Equal(t, []int{2, 1}, slices.Collect(p.ActiveIDs())) + + // 2 -> 0 + newCurrent, newInactive = p.Rotate() + + assert.Equal(t, 0, newCurrent) + p.CurrentIDFunc(func(pid int) { + assert.Equal(t, 0, pid) + }) + assert.Equal(t, 1, newInactive) + assert.Equal(t, []int{0, 2}, slices.Collect(p.ActiveIDs())) +} + +func TestPartitionerCurrentID(t *testing.T) { + p := NewPartitioner(2, 1) + + p.CurrentIDFunc(func(pid int) { + assert.Equal(t, 1, pid) + }) + assert.Equal(t, []int{1, 0}, slices.Collect(p.ActiveIDs())) +} + +func TestPartitioner_ActiveIDs_Concurrent(t *testing.T) { + wg := sync.WaitGroup{} + wg.Add(1) + p := NewPartitioner(2, 0) + rotate := make(chan struct{}) + go func() { + <-rotate + newCurrent, newInactive := p.Rotate() + assert.Equal(t, 1, newCurrent) + assert.Equal(t, 2, newInactive) + wg.Done() + }() + var activeIDs []int + for pid := range p.ActiveIDs() { + if rotate != nil { + rotate <- struct{}{} // blocks + } + rotate = nil + activeIDs = append(activeIDs, pid) + } + assert.Equal(t, []int{0, 2}, activeIDs) + wg.Wait() +} + +func TestPartitioner_CurrentIDFunc_Concurrent(t *testing.T) { + wg := sync.WaitGroup{} + wg.Add(1) + p := NewPartitioner(2, 0) + rotate := make(chan struct{}) + go func() { + <-rotate + newCurrent, newInactive := p.Rotate() + assert.Equal(t, 1, newCurrent) + assert.Equal(t, 2, newInactive) + wg.Done() + }() + p.CurrentIDFunc(func(pid int) { + rotate <- struct{}{} // blocks + assert.Equal(t, 0, pid) + }) + wg.Wait() +} diff --git a/x-pack/apm-server/sampling/eventstorage/pebble.go b/x-pack/apm-server/sampling/eventstorage/pebble.go new file mode 100644 index 00000000000..319836c622d --- /dev/null +++ b/x-pack/apm-server/sampling/eventstorage/pebble.go @@ -0,0 +1,74 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License 2.0; +// you may not use this file except in compliance with the Elastic License 2.0. + +package eventstorage + +import ( + "bytes" + "path/filepath" + + "github.com/cockroachdb/pebble/v2" + "github.com/cockroachdb/pebble/v2/bloom" + + "github.com/elastic/apm-server/internal/logs" + "github.com/elastic/elastic-agent-libs/logp" +) + +func eventComparer() *pebble.Comparer { + comparer := *pebble.DefaultComparer + // Required for prefix bloom filter + comparer.Split = func(k []byte) int { + if idx := bytes.IndexByte(k, traceIDSeparator); idx != -1 { + return idx + 1 + } + // If traceID separator does not exist, consider the entire key as prefix. + // This is required for deletes like DeleteRange([]byte{0}, []byte{1}) to work without specifying the separator. + return len(k) + } + comparer.Compare = func(a, b []byte) int { + ap := comparer.Split(a) // a prefix length + bp := comparer.Split(b) // b prefix length + if prefixCmp := bytes.Compare(a[:ap], b[:bp]); prefixCmp != 0 { + return prefixCmp + } + return comparer.ComparePointSuffixes(a[ap:], b[bp:]) + } + comparer.Name = "apmserver.EventComparer" + return &comparer +} + +func OpenEventPebble(storageDir string) (*pebble.DB, error) { + opts := &pebble.Options{ + FormatMajorVersion: pebble.FormatColumnarBlocks, + Logger: logp.NewLogger(logs.Sampling), + MemTableSize: 16 << 20, + Levels: []pebble.LevelOptions{ + { + BlockSize: 16 << 10, + Compression: func() pebble.Compression { return pebble.SnappyCompression }, + FilterPolicy: bloom.FilterPolicy(10), + FilterType: pebble.TableFilter, + }, + }, + Comparer: eventComparer(), + } + opts.Experimental.MaxWriterConcurrency = 1 // >0 enables parallel writers, the actual value doesn't matter + return pebble.Open(filepath.Join(storageDir, "event"), opts) +} + +func OpenDecisionPebble(storageDir string) (*pebble.DB, error) { + return pebble.Open(filepath.Join(storageDir, "decision"), &pebble.Options{ + FormatMajorVersion: pebble.FormatColumnarBlocks, + Logger: logp.NewLogger(logs.Sampling), + MemTableSize: 2 << 20, + Levels: []pebble.LevelOptions{ + { + BlockSize: 2 << 10, + Compression: func() pebble.Compression { return pebble.NoCompression }, + FilterPolicy: bloom.FilterPolicy(10), + FilterType: pebble.TableFilter, + }, + }, + }) +} diff --git a/x-pack/apm-server/sampling/eventstorage/pebble_test.go b/x-pack/apm-server/sampling/eventstorage/pebble_test.go new file mode 100644 index 00000000000..e2ec93a914b --- /dev/null +++ b/x-pack/apm-server/sampling/eventstorage/pebble_test.go @@ -0,0 +1,29 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License 2.0; +// you may not use this file except in compliance with the Elastic License 2.0. + +package eventstorage + +import ( + "testing" + + "github.com/cockroachdb/pebble/v2" + "github.com/stretchr/testify/assert" +) + +func TestEventComparer(t *testing.T) { + err := pebble.CheckComparer(eventComparer(), [][]byte{ + []byte("12:"), + []byte("123:"), + []byte("foo1:"), + []byte("foo12:"), + []byte("foo2:"), + }, [][]byte{ + []byte("12"), + []byte("123"), + []byte("bar1"), + []byte("bar12"), + []byte("bar2"), + }) + assert.NoError(t, err) +} diff --git a/x-pack/apm-server/sampling/eventstorage/prefix.go b/x-pack/apm-server/sampling/eventstorage/prefix.go new file mode 100644 index 00000000000..99f18d02f04 --- /dev/null +++ b/x-pack/apm-server/sampling/eventstorage/prefix.go @@ -0,0 +1,143 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License 2.0; +// you may not use this file except in compliance with the Elastic License 2.0. + +package eventstorage + +import ( + "bytes" + "errors" + "fmt" + + "github.com/cockroachdb/pebble/v2" + + "github.com/elastic/apm-data/model/modelpb" +) + +const ( + // NOTE(axw) these values (and their meanings) must remain stable + // over time, to avoid misinterpreting historical data. + entryMetaTraceSampled byte = 's' + entryMetaTraceUnsampled byte = 'u' + + // traceIDSeparator is the separator between trace ID and transaction / span ID + traceIDSeparator byte = ':' +) + +var ( + // ErrNotFound is returned by the RW.IsTraceSampled method, + // for non-existing trace IDs. + ErrNotFound = errors.New("key not found") + + // Reuse sampling decision value byte slices for performance + traceSampledVal = []byte{entryMetaTraceSampled} + traceUnsampledVal = []byte{entryMetaTraceUnsampled} +) + +func NewPrefixReadWriter(db db, prefix byte, codec Codec) PrefixReadWriter { + return PrefixReadWriter{db: db, prefix: prefix, codec: codec} +} + +// PrefixReadWriter is a helper RW that reads from and writes to db with a prefix byte in key. +type PrefixReadWriter struct { + db db + prefix byte + codec Codec +} + +// ReadTraceEvents reads rw.db using a key consisting of rw.prefix and traceID, and appends results to out. +func (rw PrefixReadWriter) ReadTraceEvents(traceID string, out *modelpb.Batch) error { + var b bytes.Buffer + b.Grow(1 + len(traceID) + 1) + b.WriteByte(rw.prefix) + b.WriteString(traceID) + b.WriteByte(traceIDSeparator) + + iter, err := rw.db.NewIter(&pebble.IterOptions{}) + if err != nil { + return err + } + defer iter.Close() + + // SeekPrefixGE uses prefix bloom filter for on disk tables. + // These bloom filters are cached in memory, and a "miss" on bloom filter avoids disk IO to check the actual table. + // Memtables still need to be scanned as pebble has no bloom filter on memtables. + // + // SeekPrefixGE ensures the prefix is present and does not require lower bound and upper bound to be set on iterator. + if valid := iter.SeekPrefixGE(b.Bytes()); !valid { + return nil + } + for ; iter.Valid(); iter.Next() { + event := &modelpb.APMEvent{} + data, err := iter.ValueAndErr() + if err != nil { + return err + } + if err := rw.codec.DecodeEvent(data, event); err != nil { + return fmt.Errorf("codec failed to decode event: %w", err) + } + *out = append(*out, event) + } + return nil +} + +// WriteTraceEvent writes encoded event as value to rw.db with key consisting of rw.prefix, traceID and id. +func (rw PrefixReadWriter) WriteTraceEvent(traceID, id string, event *modelpb.APMEvent) error { + data, err := rw.codec.EncodeEvent(event) + if err != nil { + return err + } + var b bytes.Buffer + b.Grow(1 + len(traceID) + 1 + len(id)) + b.WriteByte(rw.prefix) + b.WriteString(traceID) + b.WriteByte(traceIDSeparator) + b.WriteString(id) + key := b.Bytes() + return rw.db.Set(key, data, pebble.NoSync) +} + +// WriteTraceSampled writes sampling decision sampled to rw.db with key consisting of rw.prefix and traceID. +func (rw PrefixReadWriter) WriteTraceSampled(traceID string, sampled bool) error { + var b bytes.Buffer + b.Grow(1 + len(traceID)) + b.WriteByte(rw.prefix) + b.WriteString(traceID) + + val := traceUnsampledVal + if sampled { + val = traceSampledVal + } + return rw.db.Set(b.Bytes(), val, pebble.NoSync) +} + +// IsTraceSampled reads sampling decision from rw.db using a key consisting of rw.prefix and traceID. +// Returns ErrNotFound if trace sampling decision is not found. +func (rw PrefixReadWriter) IsTraceSampled(traceID string) (bool, error) { + var b bytes.Buffer + b.Grow(1 + len(traceID)) + b.WriteByte(rw.prefix) + b.WriteString(traceID) + + item, closer, err := rw.db.Get(b.Bytes()) + if err == pebble.ErrNotFound { + return false, ErrNotFound + } else if err != nil { + return false, err + } + defer closer.Close() + return item[0] == entryMetaTraceSampled, nil +} + +// DeleteTraceEvent deletes event associated with key consisting of rw.prefix, traceID and id from rw.db. +func (rw PrefixReadWriter) DeleteTraceEvent(traceID, id string) error { + var b bytes.Buffer + b.Grow(1 + len(traceID) + 1 + len(id)) + b.WriteByte(rw.prefix) + b.WriteString(traceID) + b.WriteByte(traceIDSeparator) + b.WriteString(id) + key := b.Bytes() + + return rw.db.Delete(key, pebble.NoSync) +} diff --git a/x-pack/apm-server/sampling/eventstorage/prefix_test.go b/x-pack/apm-server/sampling/eventstorage/prefix_test.go new file mode 100644 index 00000000000..b54696e6a3e --- /dev/null +++ b/x-pack/apm-server/sampling/eventstorage/prefix_test.go @@ -0,0 +1,180 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License 2.0; +// you may not use this file except in compliance with the Elastic License 2.0. + +package eventstorage_test + +import ( + "fmt" + "testing" + + "github.com/cockroachdb/pebble/v2" + "github.com/gofrs/uuid/v5" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/elastic/apm-data/model/modelpb" + "github.com/elastic/apm-server/x-pack/apm-server/sampling/eventstorage" +) + +func newEventPebble(t *testing.T) *pebble.DB { + db, err := eventstorage.OpenEventPebble(t.TempDir()) + require.NoError(t, err) + t.Cleanup(func() { + db.Close() + }) + return db +} + +func newDecisionPebble(t *testing.T) *pebble.DB { + db, err := eventstorage.OpenDecisionPebble(t.TempDir()) + require.NoError(t, err) + t.Cleanup(func() { + db.Close() + }) + return db +} + +func TestPrefixReadWriter_WriteTraceEvent(t *testing.T) { + codec := eventstorage.ProtobufCodec{} + db := newEventPebble(t) + traceID := "foo" + txnID := "bar" + txn := makeTransaction(txnID, traceID) + rw := eventstorage.NewPrefixReadWriter(db, 1, codec) + + check := func() { + err := rw.WriteTraceEvent(traceID, txnID, txn) + assert.NoError(t, err) + item, closer, err := db.Get(append([]byte{1}, []byte("foo:bar")...)) + assert.NoError(t, err) + defer closer.Close() + var actual modelpb.APMEvent + err = codec.DecodeEvent(item, &actual) + assert.NoError(t, err) + assert.Equal(t, *txn, actual) + } + + check() + + // Try writing to the same key again to simulate misbehaving agent / race condition + check() +} + +func TestPrefixReadWriter_ReadTraceEvents(t *testing.T) { + codec := eventstorage.ProtobufCodec{} + db := newEventPebble(t) + rw := eventstorage.NewPrefixReadWriter(db, 1, codec) + + traceID := "foo1" + for _, txnID := range []string{"bar", "baz"} { + txn := makeTransaction(txnID, traceID) + err := rw.WriteTraceEvent(traceID, txnID, txn) + require.NoError(t, err) + } + + // Create transactions with similar trace IDs to ensure that iterator upper bound is enforced + txn := makeTransaction("bar", "foo2") + err := rw.WriteTraceEvent("foo2", "bar", txn) + require.NoError(t, err) + + txn = makeTransaction("bar", "foo12") + err = rw.WriteTraceEvent("foo12", "bar", txn) + require.NoError(t, err) + + var out modelpb.Batch + err = rw.ReadTraceEvents(traceID, &out) + assert.NoError(t, err) + assert.Equal(t, modelpb.Batch{ + makeTransaction("bar", traceID), + makeTransaction("baz", traceID), + }, out) +} + +func TestPrefixReadWriter_DeleteTraceEvent(t *testing.T) { + codec := eventstorage.ProtobufCodec{} + db := newEventPebble(t) + traceID := "foo" + txnID := "bar" + txn := makeTransaction(txnID, traceID) + rw := eventstorage.NewPrefixReadWriter(db, 1, codec) + err := rw.WriteTraceEvent(traceID, txnID, txn) + require.NoError(t, err) + + key := append([]byte{1}, []byte("foo:bar")...) + + _, closer, err := db.Get(key) + assert.NoError(t, err) + err = closer.Close() + assert.NoError(t, err) + + err = rw.DeleteTraceEvent(traceID, txnID) + assert.NoError(t, err) + + _, _, err = db.Get(key) + assert.ErrorIs(t, err, pebble.ErrNotFound) +} + +func TestPrefixReadWriter_WriteTraceSampled(t *testing.T) { + for _, sampled := range []bool{true, false} { + t.Run(fmt.Sprintf("sampled=%v", sampled), func(t *testing.T) { + codec := eventstorage.ProtobufCodec{} + db := newDecisionPebble(t) + traceID := "foo" + rw := eventstorage.NewPrefixReadWriter(db, 1, codec) + + check := func() { + err := rw.WriteTraceSampled(traceID, sampled) + assert.NoError(t, err) + item, closer, err := db.Get(append([]byte{1}, []byte("foo")...)) + assert.NoError(t, err) + defer closer.Close() + assert.NoError(t, err) + if sampled { + assert.Equal(t, []byte{'s'}, item) + } else { + assert.Equal(t, []byte{'u'}, item) + } + } + + check() + + // Try writing to the same key again to simulate misbehaving agent / race condition + check() + }) + } +} + +func TestPrefixReadWriter_IsTraceSampled(t *testing.T) { + for _, tc := range []struct { + sampled bool + missing bool + }{ + { + sampled: true, + }, + { + sampled: false, + }, + { + missing: true, + }, + } { + t.Run(fmt.Sprintf("sampled=%v,missing=%v", tc.sampled, tc.missing), func(t *testing.T) { + db := newDecisionPebble(t) + rw := eventstorage.NewPrefixReadWriter(db, 1, nopCodec{}) + traceID := uuid.Must(uuid.NewV4()).String() + if !tc.missing { + err := rw.WriteTraceSampled(traceID, tc.sampled) + require.NoError(t, err) + } + sampled, err := rw.IsTraceSampled(traceID) + if tc.missing { + assert.ErrorIs(t, err, eventstorage.ErrNotFound) + } else { + assert.NoError(t, err) + assert.Equal(t, tc.sampled, sampled) + } + }) + } +} diff --git a/x-pack/apm-server/sampling/eventstorage/rw.go b/x-pack/apm-server/sampling/eventstorage/rw.go new file mode 100644 index 00000000000..be208cb3f0a --- /dev/null +++ b/x-pack/apm-server/sampling/eventstorage/rw.go @@ -0,0 +1,120 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License 2.0; +// you may not use this file except in compliance with the Elastic License 2.0. + +package eventstorage + +import ( + "errors" + "fmt" + + "github.com/elastic/apm-data/model/modelpb" +) + +var ( + // ErrLimitReached is returned by RW methods when storage usage + // is greater than configured limit. + ErrLimitReached = errors.New("configured storage limit reached") +) + +// RW is a read writer interface that has methods to read and write trace event and sampling decisions. +type RW interface { + ReadTraceEvents(traceID string, out *modelpb.Batch) error + WriteTraceEvent(traceID, id string, event *modelpb.APMEvent) error + WriteTraceSampled(traceID string, sampled bool) error + IsTraceSampled(traceID string) (bool, error) + DeleteTraceEvent(traceID, id string) error +} + +// SplitReadWriter is a RW that splits method calls to eventRW and decisionRW. +// - *TraceEvent* method calls are passed through to eventRW. +// - *TraceSampled method calls are passed through to decisionRW. +type SplitReadWriter struct { + eventRW, decisionRW RW +} + +func (s SplitReadWriter) ReadTraceEvents(traceID string, out *modelpb.Batch) error { + return s.eventRW.ReadTraceEvents(traceID, out) +} + +func (s SplitReadWriter) WriteTraceEvent(traceID, id string, event *modelpb.APMEvent) error { + return s.eventRW.WriteTraceEvent(traceID, id, event) +} + +func (s SplitReadWriter) WriteTraceSampled(traceID string, sampled bool) error { + return s.decisionRW.WriteTraceSampled(traceID, sampled) +} + +func (s SplitReadWriter) IsTraceSampled(traceID string) (bool, error) { + return s.decisionRW.IsTraceSampled(traceID) +} + +func (s SplitReadWriter) DeleteTraceEvent(traceID, id string) error { + return s.eventRW.DeleteTraceEvent(traceID, id) +} + +func (s SplitReadWriter) Close() error { + return nil +} + +type storageLimitChecker interface { + DiskUsage() uint64 + StorageLimit() uint64 +} + +// StorageLimitReadWriter is a RW that forbids Write* method calls based on disk usage and limit from storageLimitChecker. +// If there is no limit or limit is not reached, method calls are passed through to nextRW. +type StorageLimitReadWriter struct { + checker storageLimitChecker + nextRW RW +} + +func NewStorageLimitReadWriter(checker storageLimitChecker, nextRW RW) StorageLimitReadWriter { + return StorageLimitReadWriter{ + checker: checker, + nextRW: nextRW, + } +} + +func (s StorageLimitReadWriter) checkStorageLimit() error { + limit := s.checker.StorageLimit() + if limit != 0 { // unlimited storage + usage := s.checker.DiskUsage() + if usage >= limit { + return fmt.Errorf("%w (current: %d, limit %d)", ErrLimitReached, usage, limit) + } + } + return nil +} + +// ReadTraceEvents passes through to s.nextRW.ReadTraceEvents. +func (s StorageLimitReadWriter) ReadTraceEvents(traceID string, out *modelpb.Batch) error { + return s.nextRW.ReadTraceEvents(traceID, out) +} + +// WriteTraceEvent passes through to s.nextRW.WriteTraceEvent only if storage limit is not reached. +func (s StorageLimitReadWriter) WriteTraceEvent(traceID, id string, event *modelpb.APMEvent) error { + if err := s.checkStorageLimit(); err != nil { + return err + } + return s.nextRW.WriteTraceEvent(traceID, id, event) +} + +// WriteTraceSampled passes through to s.nextRW.WriteTraceSampled only if storage limit is not reached. +func (s StorageLimitReadWriter) WriteTraceSampled(traceID string, sampled bool) error { + if err := s.checkStorageLimit(); err != nil { + return err + } + return s.nextRW.WriteTraceSampled(traceID, sampled) +} + +// IsTraceSampled passes through to s.nextRW.IsTraceSampled. +func (s StorageLimitReadWriter) IsTraceSampled(traceID string) (bool, error) { + return s.nextRW.IsTraceSampled(traceID) +} + +// DeleteTraceEvent passes through to s.nextRW.DeleteTraceEvent. +func (s StorageLimitReadWriter) DeleteTraceEvent(traceID, id string) error { + // Technically DeleteTraceEvent writes, but it should have a net effect of reducing disk usage + return s.nextRW.DeleteTraceEvent(traceID, id) +} diff --git a/x-pack/apm-server/sampling/eventstorage/rw_test.go b/x-pack/apm-server/sampling/eventstorage/rw_test.go new file mode 100644 index 00000000000..bcf6490c16d --- /dev/null +++ b/x-pack/apm-server/sampling/eventstorage/rw_test.go @@ -0,0 +1,109 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License 2.0; +// you may not use this file except in compliance with the Elastic License 2.0. + +package eventstorage_test + +import ( + "fmt" + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/elastic/apm-data/model/modelpb" + "github.com/elastic/apm-server/x-pack/apm-server/sampling/eventstorage" +) + +type mockChecker struct { + usage, limit uint64 +} + +func (m mockChecker) DiskUsage() uint64 { + return m.usage +} + +func (m mockChecker) StorageLimit() uint64 { + return m.limit +} + +type mockRW struct { + callback func() +} + +func (m mockRW) ReadTraceEvents(traceID string, out *modelpb.Batch) error { + m.callback() + return nil +} + +func (m mockRW) WriteTraceEvent(traceID, id string, event *modelpb.APMEvent) error { + m.callback() + return nil +} + +func (m mockRW) WriteTraceSampled(traceID string, sampled bool) error { + m.callback() + return nil +} + +func (m mockRW) IsTraceSampled(traceID string) (bool, error) { + m.callback() + return false, nil +} + +func (m mockRW) DeleteTraceEvent(traceID, id string) error { + m.callback() + return nil +} + +func (m mockRW) Flush() error { + m.callback() + return nil +} + +func TestStorageLimitReadWriter(t *testing.T) { + for _, tt := range []struct { + limit, usage uint64 + wantCalled bool + }{ + { + limit: 0, // unlimited + usage: 1, + wantCalled: true, + }, + { + limit: 2, + usage: 3, + wantCalled: false, + }, + } { + t.Run(fmt.Sprintf("limit=%d,usage=%d", tt.limit, tt.usage), func(t *testing.T) { + checker := mockChecker{limit: tt.limit, usage: tt.usage} + var callCount int + rw := eventstorage.NewStorageLimitReadWriter(checker, mockRW{ + callback: func() { + callCount++ + }, + }) + assert.NoError(t, rw.ReadTraceEvents("foo", nil)) + _, err := rw.IsTraceSampled("foo") + assert.NoError(t, err) + assert.NoError(t, rw.DeleteTraceEvent("foo", "bar")) + + err = rw.WriteTraceEvent("foo", "bar", nil) + if tt.wantCalled { + assert.NoError(t, err) + assert.Equal(t, 4, callCount) + } else { + assert.Error(t, err) + } + err = rw.WriteTraceSampled("foo", true) + if tt.wantCalled { + assert.NoError(t, err) + assert.Equal(t, 5, callCount) + } else { + assert.Error(t, err) + } + }) + } + +} diff --git a/x-pack/apm-server/sampling/eventstorage/sharded.go b/x-pack/apm-server/sampling/eventstorage/sharded.go deleted file mode 100644 index 032f3fddad7..00000000000 --- a/x-pack/apm-server/sampling/eventstorage/sharded.go +++ /dev/null @@ -1,136 +0,0 @@ -// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one -// or more contributor license agreements. Licensed under the Elastic License 2.0; -// you may not use this file except in compliance with the Elastic License 2.0. - -package eventstorage - -import ( - "errors" - "runtime" - "sync" - - "github.com/cespare/xxhash/v2" - - "github.com/elastic/apm-data/model/modelpb" -) - -// ShardedReadWriter provides sharded, locked, access to a Storage. -// -// ShardedReadWriter shards on trace ID. -type ShardedReadWriter struct { - readWriters []lockedReadWriter -} - -func newShardedReadWriter(storage *Storage) *ShardedReadWriter { - s := &ShardedReadWriter{ - // Create as many ReadWriters as there are GOMAXPROCS, which considers - // cgroup quotas, so we can ideally minimise lock contention, and scale - // up accordingly with more CPU. - readWriters: make([]lockedReadWriter, runtime.GOMAXPROCS(0)), - } - for i := range s.readWriters { - s.readWriters[i].rw = storage.NewReadWriter() - } - return s -} - -// Close closes all sharded storage readWriters. -func (s *ShardedReadWriter) Close() { - for i := range s.readWriters { - s.readWriters[i].Close() - } -} - -// Flush flushes all sharded storage readWriters. -func (s *ShardedReadWriter) Flush() error { - var errs []error - for i := range s.readWriters { - if err := s.readWriters[i].Flush(); err != nil { - errs = append(errs, err) - } - } - return errors.Join(errs...) -} - -// ReadTraceEvents calls Writer.ReadTraceEvents, using a sharded, locked, Writer. -func (s *ShardedReadWriter) ReadTraceEvents(traceID string, out *modelpb.Batch) error { - return s.getWriter(traceID).ReadTraceEvents(traceID, out) -} - -// WriteTraceEvent calls Writer.WriteTraceEvent, using a sharded, locked, Writer. -func (s *ShardedReadWriter) WriteTraceEvent(traceID, id string, event *modelpb.APMEvent, opts WriterOpts) error { - return s.getWriter(traceID).WriteTraceEvent(traceID, id, event, opts) -} - -// WriteTraceSampled calls Writer.WriteTraceSampled, using a sharded, locked, Writer. -func (s *ShardedReadWriter) WriteTraceSampled(traceID string, sampled bool, opts WriterOpts) error { - return s.getWriter(traceID).WriteTraceSampled(traceID, sampled, opts) -} - -// IsTraceSampled calls Writer.IsTraceSampled, using a sharded, locked, Writer. -func (s *ShardedReadWriter) IsTraceSampled(traceID string) (bool, error) { - return s.getWriter(traceID).IsTraceSampled(traceID) -} - -// DeleteTraceEvent calls Writer.DeleteTraceEvent, using a sharded, locked, Writer. -func (s *ShardedReadWriter) DeleteTraceEvent(traceID, id string) error { - return s.getWriter(traceID).DeleteTraceEvent(traceID, id) -} - -// getWriter returns an event storage writer for the given trace ID. -// -// This method is idempotent, which is necessary to avoid transaction -// conflicts and ensure all events are reported once a sampling decision -// has been recorded. -func (s *ShardedReadWriter) getWriter(traceID string) *lockedReadWriter { - var h xxhash.Digest - h.WriteString(traceID) - return &s.readWriters[h.Sum64()%uint64(len(s.readWriters))] -} - -type lockedReadWriter struct { - mu sync.Mutex - rw *ReadWriter -} - -func (rw *lockedReadWriter) Close() { - rw.mu.Lock() - defer rw.mu.Unlock() - rw.rw.Close() -} - -func (rw *lockedReadWriter) Flush() error { - rw.mu.Lock() - defer rw.mu.Unlock() - return rw.rw.Flush() -} - -func (rw *lockedReadWriter) ReadTraceEvents(traceID string, out *modelpb.Batch) error { - rw.mu.Lock() - defer rw.mu.Unlock() - return rw.rw.ReadTraceEvents(traceID, out) -} - -func (rw *lockedReadWriter) WriteTraceEvent(traceID, id string, event *modelpb.APMEvent, opts WriterOpts) error { - rw.mu.Lock() - defer rw.mu.Unlock() - return rw.rw.WriteTraceEvent(traceID, id, event, opts) -} - -func (rw *lockedReadWriter) WriteTraceSampled(traceID string, sampled bool, opts WriterOpts) error { - rw.mu.Lock() - defer rw.mu.Unlock() - return rw.rw.WriteTraceSampled(traceID, sampled, opts) -} - -func (rw *lockedReadWriter) IsTraceSampled(traceID string) (bool, error) { - rw.mu.Lock() - defer rw.mu.Unlock() - return rw.rw.IsTraceSampled(traceID) -} - -func (rw *lockedReadWriter) DeleteTraceEvent(traceID, id string) error { - rw.mu.Lock() - defer rw.mu.Unlock() - return rw.rw.DeleteTraceEvent(traceID, id) -} diff --git a/x-pack/apm-server/sampling/eventstorage/sharded_bench_test.go b/x-pack/apm-server/sampling/eventstorage/sharded_bench_test.go deleted file mode 100644 index 1d26986eed6..00000000000 --- a/x-pack/apm-server/sampling/eventstorage/sharded_bench_test.go +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one -// or more contributor license agreements. Licensed under the Elastic License 2.0; -// you may not use this file except in compliance with the Elastic License 2.0. - -package eventstorage_test - -import ( - "testing" - "time" - - "github.com/gofrs/uuid" - - "github.com/elastic/apm-data/model/modelpb" - "github.com/elastic/apm-server/x-pack/apm-server/sampling/eventstorage" -) - -func BenchmarkShardedWriteTransactionUncontended(b *testing.B) { - db := newBadgerDB(b, badgerOptions) - store := eventstorage.New(db, eventstorage.ProtobufCodec{}) - sharded := store.NewShardedReadWriter() - defer sharded.Close() - wOpts := eventstorage.WriterOpts{ - TTL: time.Minute, - StorageLimitInBytes: 0, - } - - b.RunParallel(func(pb *testing.PB) { - traceID := uuid.Must(uuid.NewV4()).String() - transaction := &modelpb.APMEvent{ - Transaction: &modelpb.Transaction{Id: traceID}, - } - for pb.Next() { - if err := sharded.WriteTraceEvent(traceID, traceID, transaction, wOpts); err != nil { - b.Fatal(err) - } - } - }) -} - -func BenchmarkShardedWriteTransactionContended(b *testing.B) { - db := newBadgerDB(b, badgerOptions) - store := eventstorage.New(db, eventstorage.ProtobufCodec{}) - sharded := store.NewShardedReadWriter() - defer sharded.Close() - wOpts := eventstorage.WriterOpts{ - TTL: time.Minute, - StorageLimitInBytes: 0, - } - - // Use a single trace ID, causing all events to go through - // the same sharded writer, contending for a single lock. - traceID := uuid.Must(uuid.NewV4()).String() - - b.RunParallel(func(pb *testing.PB) { - transactionID := uuid.Must(uuid.NewV4()).String() - transaction := &modelpb.APMEvent{ - Transaction: &modelpb.Transaction{Id: transactionID}, - } - for pb.Next() { - if err := sharded.WriteTraceEvent(traceID, transactionID, transaction, wOpts); err != nil { - b.Fatal(err) - } - } - }) -} diff --git a/x-pack/apm-server/sampling/eventstorage/storage.go b/x-pack/apm-server/sampling/eventstorage/storage.go index d8dad34ab7d..41b5a63302a 100644 --- a/x-pack/apm-server/sampling/eventstorage/storage.go +++ b/x-pack/apm-server/sampling/eventstorage/storage.go @@ -5,45 +5,26 @@ package eventstorage import ( - "bytes" - "errors" - "fmt" - "sync/atomic" - "time" + "io" - "github.com/dgraph-io/badger/v2" + "github.com/cockroachdb/pebble/v2" "github.com/elastic/apm-data/model/modelpb" ) -const ( - // NOTE(axw) these values (and their meanings) must remain stable - // over time, to avoid misinterpreting historical data. - entryMetaTraceSampled = 's' - entryMetaTraceUnsampled = 'u' - entryMetaTraceEvent = 'e' - - // Initial transaction size - // len(txnKey) + 10 - baseTransactionSize = 10 + 11 -) - -var ( - // ErrNotFound is returned by by the Storage.IsTraceSampled method, - // for non-existing trace IDs. - ErrNotFound = errors.New("key not found") - - // ErrLimitReached is returned by the ReadWriter.Flush method when - // the configured StorageLimiter.Limit is true. - ErrLimitReached = errors.New("configured storage limit reached") -) +// db is a key value database interface. +type db interface { + Get(key []byte) ([]byte, io.Closer, error) + Set(key, value []byte, opts *pebble.WriteOptions) error + Delete(key []byte, opts *pebble.WriteOptions) error + NewIter(o *pebble.IterOptions) (*pebble.Iterator, error) +} // Storage provides storage for sampled transactions and spans, // and for recording trace sampling decisions. type Storage struct { - db *badger.DB - // pendingSize tracks the total size of pending writes across ReadWriters - pendingSize *atomic.Int64 + db db + partitioner *Partitioner codec Codec } @@ -54,266 +35,18 @@ type Codec interface { } // New returns a new Storage using db and codec. -func New(db *badger.DB, codec Codec) *Storage { - return &Storage{db: db, pendingSize: &atomic.Int64{}, codec: codec} -} - -// NewShardedReadWriter returns a new ShardedReadWriter, for sharded -// reading and writing. -// -// The returned ShardedReadWriter must be closed when it is no longer -// needed. -func (s *Storage) NewShardedReadWriter() *ShardedReadWriter { - return newShardedReadWriter(s) -} - -// NewReadWriter returns a new ReadWriter for reading events from and -// writing events to storage. -// -// The returned ReadWriter must be closed when it is no longer needed. -func (s *Storage) NewReadWriter() *ReadWriter { - s.pendingSize.Add(baseTransactionSize) - return &ReadWriter{ - s: s, - txn: s.db.NewTransaction(true), - pendingSize: baseTransactionSize, - } -} - -// WriterOpts provides configuration options for writes to storage -type WriterOpts struct { - TTL time.Duration - StorageLimitInBytes int64 -} - -// ReadWriter provides a means of reading events from storage, and batched -// writing of events to storage. -// -// ReadWriter is not safe for concurrent access. All operations that involve -// a given trace ID should be performed with the same ReadWriter in order to -// avoid conflicts, e.g. by using consistent hashing to distribute to one of -// a set of ReadWriters, such as implemented by ShardedReadWriter. -type ReadWriter struct { - s *Storage - txn *badger.Txn - - // readKeyBuf is a reusable buffer for keys used in read operations. - // This must not be used in write operations, as keys are expected to - // be unmodified until the end of a transaction. - readKeyBuf []byte - pendingWrites int - // pendingSize tracks the size of pending writes in the current ReadWriter - pendingSize int64 -} - -// Close closes the writer. Any writes that have not been flushed may be lost. -// -// This must be called when the writer is no longer needed, in order to reclaim -// resources. -func (rw *ReadWriter) Close() { - rw.txn.Discard() -} - -// Flush waits for preceding writes to be committed to storage. -// -// Flush must be called to ensure writes are committed to storage. -// If Flush is not called before the writer is closed, then writes -// may be lost. -func (rw *ReadWriter) Flush() error { - const flushErrFmt = "failed to flush pending writes: %w" - err := rw.txn.Commit() - rw.txn = rw.s.db.NewTransaction(true) - rw.s.pendingSize.Add(-rw.pendingSize) - rw.pendingWrites = 0 - rw.pendingSize = baseTransactionSize - rw.s.pendingSize.Add(baseTransactionSize) - if err != nil { - return fmt.Errorf(flushErrFmt, err) - } - return nil -} - -// WriteTraceSampled records the tail-sampling decision for the given trace ID. -func (rw *ReadWriter) WriteTraceSampled(traceID string, sampled bool, opts WriterOpts) error { - key := []byte(traceID) - var meta uint8 = entryMetaTraceUnsampled - if sampled { - meta = entryMetaTraceSampled - } - return rw.writeEntry(badger.NewEntry(key[:], nil).WithMeta(meta), opts) -} - -// IsTraceSampled reports whether traceID belongs to a trace that is sampled -// or unsampled. If no sampling decision has been recorded, IsTraceSampled -// returns ErrNotFound. -func (rw *ReadWriter) IsTraceSampled(traceID string) (bool, error) { - rw.readKeyBuf = append(rw.readKeyBuf[:0], traceID...) - item, err := rw.txn.Get(rw.readKeyBuf) - if err != nil { - if err == badger.ErrKeyNotFound { - return false, ErrNotFound - } - return false, err +func New(db db, partitioner *Partitioner, codec Codec) *Storage { + return &Storage{ + db: db, + partitioner: partitioner, + codec: codec, } - return item.UserMeta() == entryMetaTraceSampled, nil } -// WriteTraceEvent writes a trace event to storage. -// -// WriteTraceEvent may return before the write is committed to storage. -// Call Flush to ensure the write is committed. -func (rw *ReadWriter) WriteTraceEvent(traceID string, id string, event *modelpb.APMEvent, opts WriterOpts) error { - data, err := rw.s.codec.EncodeEvent(event) - if err != nil { - return err - } - var buf bytes.Buffer - buf.Grow(len(traceID) + 1 + len(id)) - buf.WriteString(traceID) - buf.WriteByte(':') - buf.WriteString(id) - key := buf.Bytes() - return rw.writeEntry(badger.NewEntry(key, data).WithMeta(entryMetaTraceEvent), opts) -} - -func (rw *ReadWriter) writeEntry(e *badger.Entry, opts WriterOpts) error { - rw.pendingWrites++ - entrySize := estimateSize(e) - // The badger database has an async size reconciliation, with a 1 minute - // ticker that keeps the lsm and vlog sizes updated in an in-memory map. - // It's OK to call call s.db.Size() on the hot path, since the memory - // lookup is cheap. - lsm, vlog := rw.s.db.Size() - - // there are multiple ReadWriters writing to the same storage so add - // the entry size and consider the new value to avoid TOCTOU issues. - pendingSize := rw.s.pendingSize.Add(entrySize) - rw.pendingSize += entrySize - - if current := pendingSize + lsm + vlog; opts.StorageLimitInBytes != 0 && current >= opts.StorageLimitInBytes { - // flush what we currently have and discard the current entry - if err := rw.Flush(); err != nil { - return err - } - return fmt.Errorf("%w (current: %d, limit: %d)", ErrLimitReached, current, opts.StorageLimitInBytes) - } - - if rw.pendingWrites >= 200 { - // Attempt to flush if there are 200 or more uncommitted writes. - // This ensures calls to ReadTraceEvents are not slowed down; - // ReadTraceEvents uses an iterator, which must sort all keys - // of uncommitted writes. - // The 200 value yielded a good balance between read and write speed: - // https://github.com/elastic/apm-server/pull/8407#issuecomment-1162994643 - if err := rw.Flush(); err != nil { - return err - } - - // the current ReadWriter flushed the transaction and reset the pendingSize so add - // the entrySize again. - rw.pendingSize += entrySize - rw.s.pendingSize.Add(entrySize) - } - - err := rw.txn.SetEntry(e.WithTTL(opts.TTL)) - - // If the transaction is already too big to accommodate the new entry, flush - // the existing transaction and set the entry on a new one, otherwise, - // returns early. - if err != badger.ErrTxnTooBig { - return err - } - if err := rw.Flush(); err != nil { - return err - } - rw.pendingSize += entrySize - rw.s.pendingSize.Add(entrySize) - return rw.txn.SetEntry(e.WithTTL(opts.TTL)) -} - -func estimateSize(e *badger.Entry) int64 { - // See badger WithValueThreshold option - // An storage usage of an entry depends on its size - // - // if len(e.Value) < threshold { - // return len(e.Key) + len(e.Value) + 2 // Meta, UserMeta - // } - // return len(e.Key) + 12 + 2 // 12 for ValuePointer, 2 for metas. - // - // Make a good estimate by reserving more space - estimate := len(e.Key) + len(e.Value) + 12 + 2 - // Extra bytes for the version in key. - return int64(estimate) + 10 -} - -// DeleteTraceEvent deletes the trace event from storage. -func (rw *ReadWriter) DeleteTraceEvent(traceID, id string) error { - var buf bytes.Buffer - buf.Grow(len(traceID) + 1 + len(id)) - buf.WriteString(traceID) - buf.WriteByte(':') - buf.WriteString(id) - key := buf.Bytes() - - err := rw.txn.Delete(key) - // If the transaction is already too big to accommodate the new entry, flush - // the existing transaction and set the entry on a new one, otherwise, - // returns early. - if err != badger.ErrTxnTooBig { - return err - } - if err := rw.Flush(); err != nil { - return err - } - - return rw.txn.Delete(key) -} - -// ReadTraceEvents reads trace events with the given trace ID from storage into out. -func (rw *ReadWriter) ReadTraceEvents(traceID string, out *modelpb.Batch) error { - opts := badger.DefaultIteratorOptions - rw.readKeyBuf = append(append(rw.readKeyBuf[:0], traceID...), ':') - opts.Prefix = rw.readKeyBuf - - // 1st pass: check whether there exist keys matching the prefix. - // Do not prefetch values so that the check is done in-memory. - // This is to optimize for cases when it is a miss. - opts.PrefetchValues = false - iter := rw.txn.NewIterator(opts) - iter.Rewind() - if !iter.Valid() { - iter.Close() - return nil - } - iter.Close() - - // 2nd pass: this is only done when there exist keys matching the prefix. - // Fetch the events with PrefetchValues for performance. - // This is to optimize for cases when it is a hit. - opts.PrefetchValues = true - iter = rw.txn.NewIterator(opts) - defer iter.Close() - for iter.Rewind(); iter.Valid(); iter.Next() { - item := iter.Item() - if item.IsDeletedOrExpired() { - continue - } - switch item.UserMeta() { - case entryMetaTraceEvent: - event := &modelpb.APMEvent{} - if err := item.Value(func(data []byte) error { - if err := rw.s.codec.DecodeEvent(data, event); err != nil { - return fmt.Errorf("codec failed to decode event: %w", err) - } - return nil - }); err != nil { - return err - } - *out = append(*out, event) - default: - // Unknown entry meta: ignore. - continue - } +// NewReadWriter returns a new PartitionReadWriter for reading events from and +// writing events to storage. +func (s *Storage) NewReadWriter() *PartitionReadWriter { + return &PartitionReadWriter{ + s: s, } - return nil } diff --git a/x-pack/apm-server/sampling/eventstorage/storage_bench_test.go b/x-pack/apm-server/sampling/eventstorage/storage_bench_test.go index 3c5bafcf17a..fa464df323b 100644 --- a/x-pack/apm-server/sampling/eventstorage/storage_bench_test.go +++ b/x-pack/apm-server/sampling/eventstorage/storage_bench_test.go @@ -8,10 +8,8 @@ import ( "encoding/hex" "fmt" "testing" - "time" - "github.com/gofrs/uuid" - "github.com/stretchr/testify/assert" + "github.com/gofrs/uuid/v5" "github.com/elastic/apm-data/model/modelpb" "github.com/elastic/apm-server/x-pack/apm-server/sampling/eventstorage" @@ -19,10 +17,8 @@ import ( func BenchmarkWriteTransaction(b *testing.B) { test := func(b *testing.B, codec eventstorage.Codec, bigTX bool) { - db := newBadgerDB(b, badgerOptions) - store := eventstorage.New(db, codec) - readWriter := store.NewReadWriter() - defer readWriter.Close() + sm := newStorageManager(b, eventstorage.WithCodec(codec)) + readWriter := sm.NewReadWriter() traceID := hex.EncodeToString([]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}) transactionID := hex.EncodeToString([]byte{1, 2, 3, 4, 5, 6, 7, 8}) @@ -39,16 +35,11 @@ func BenchmarkWriteTransaction(b *testing.B) { b.ResetTimer() - wOpts := eventstorage.WriterOpts{ - TTL: time.Minute, - StorageLimitInBytes: 0, - } for i := 0; i < b.N; i++ { - if err := readWriter.WriteTraceEvent(traceID, transactionID, transaction, wOpts); err != nil { + if err := readWriter.WriteTraceEvent(traceID, transactionID, transaction); err != nil { b.Fatal(err) } } - assert.NoError(b, readWriter.Flush()) } type testCase struct { @@ -87,14 +78,8 @@ func BenchmarkReadEvents(b *testing.B) { counts := []int{0, 1, 10, 100, 199, 399, 1000} for _, count := range counts { b.Run(fmt.Sprintf("%d events", count), func(b *testing.B) { - db := newBadgerDB(b, badgerOptions) - store := eventstorage.New(db, codec) - readWriter := store.NewReadWriter() - defer readWriter.Close() - wOpts := eventstorage.WriterOpts{ - TTL: time.Minute, - StorageLimitInBytes: 0, - } + sm := newStorageManager(b, eventstorage.WithCodec(codec)) + readWriter := sm.NewReadWriter() for i := 0; i < count; i++ { transactionID := uuid.Must(uuid.NewV4()).String() @@ -108,13 +93,11 @@ func BenchmarkReadEvents(b *testing.B) { }, } } - if err := readWriter.WriteTraceEvent(traceID, transactionID, transaction, wOpts); err != nil { + if err := readWriter.WriteTraceEvent(traceID, transactionID, transaction); err != nil { b.Fatal(err) } } - // NOTE(marclop) We want to check how badly the read performance is affected with - // by having uncommitted events in the badger TX. b.ResetTimer() var batch modelpb.Batch for i := 0; i < b.N; i++ { @@ -167,17 +150,11 @@ func BenchmarkReadEventsHit(b *testing.B) { // And causes next iteration setup to take a very long time. const txnCountInTrace = 5 - test := func(b *testing.B, codec eventstorage.Codec, bigTX bool) { + test := func(b *testing.B, bigTX bool, reloadDB bool) { for _, hit := range []bool{false, true} { b.Run(fmt.Sprintf("hit=%v", hit), func(b *testing.B) { - db := newBadgerDB(b, badgerOptions) - store := eventstorage.New(db, codec) - readWriter := store.NewReadWriter() - defer readWriter.Close() - wOpts := eventstorage.WriterOpts{ - TTL: time.Hour, - StorageLimitInBytes: 0, - } + sm := newStorageManager(b) + readWriter := sm.NewReadWriter() traceIDs := make([]string, b.N) @@ -196,15 +173,20 @@ func BenchmarkReadEventsHit(b *testing.B) { }, } } - if err := readWriter.WriteTraceEvent(traceID, transactionID, transaction, wOpts); err != nil { + if err := readWriter.WriteTraceEvent(traceID, transactionID, transaction); err != nil { b.Fatal(err) } } } - if err := readWriter.Flush(); err != nil { - b.Fatal(err) + + if reloadDB { + if err := sm.Reload(); err != nil { + b.Fatal(err) + } } + readWriter = sm.NewReadWriter() + b.ResetTimer() var batch modelpb.Batch for i := 0; i < b.N; i++ { @@ -224,9 +206,13 @@ func BenchmarkReadEventsHit(b *testing.B) { } } - for _, bigTX := range []bool{true, false} { - b.Run(fmt.Sprintf("bigTX=%v", bigTX), func(b *testing.B) { - test(b, eventstorage.ProtobufCodec{}, bigTX) + for _, reloadDB := range []bool{false, true} { + b.Run(fmt.Sprintf("reloadDB=%v", reloadDB), func(b *testing.B) { + for _, bigTX := range []bool{true, false} { + b.Run(fmt.Sprintf("bigTX=%v", bigTX), func(b *testing.B) { + test(b, bigTX, reloadDB) + }) + } }) } } @@ -237,19 +223,13 @@ func BenchmarkIsTraceSampled(b *testing.B) { unknownTraceUUID := uuid.Must(uuid.NewV4()) // Test with varying numbers of events in the trace. - db := newBadgerDB(b, badgerOptions) - store := eventstorage.New(db, eventstorage.ProtobufCodec{}) - readWriter := store.NewReadWriter() - defer readWriter.Close() - wOpts := eventstorage.WriterOpts{ - TTL: time.Minute, - StorageLimitInBytes: 0, - } + sm := newStorageManager(b) + readWriter := sm.NewReadWriter() - if err := readWriter.WriteTraceSampled(sampledTraceUUID.String(), true, wOpts); err != nil { + if err := readWriter.WriteTraceSampled(sampledTraceUUID.String(), true); err != nil { b.Fatal(err) } - if err := readWriter.WriteTraceSampled(unsampledTraceUUID.String(), false, wOpts); err != nil { + if err := readWriter.WriteTraceSampled(unsampledTraceUUID.String(), false); err != nil { b.Fatal(err) } diff --git a/x-pack/apm-server/sampling/eventstorage/storage_manager.go b/x-pack/apm-server/sampling/eventstorage/storage_manager.go new file mode 100644 index 00000000000..9abec2117f8 --- /dev/null +++ b/x-pack/apm-server/sampling/eventstorage/storage_manager.go @@ -0,0 +1,362 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License 2.0; +// you may not use this file except in compliance with the Elastic License 2.0. + +package eventstorage + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "os" + "path/filepath" + "sync" + "sync/atomic" + "time" + + "github.com/cockroachdb/pebble/v2" + "go.opentelemetry.io/otel/metric" + "golang.org/x/sync/errgroup" + + "github.com/elastic/apm-server/internal/logs" + "github.com/elastic/elastic-agent-libs/logp" +) + +const ( + // subscriberPositionFile holds the file name used for persisting + // the subscriber position across server restarts. + subscriberPositionFile = "subscriber_position.json" + + // partitionsPerTTL holds the number of partitions that events in 1 TTL should be stored over. + // Increasing partitionsPerTTL increases read amplification, but decreases storage overhead, + // as TTL GC can be performed sooner. + // + // For example, partitionPerTTL=1 means we need to keep 2 partitions active, + // such that the last entry in the previous partition is also kept for a full TTL. + // This means storage requirement is 2 * TTL, and it needs to read 2 keys per trace ID read. + // If partitionPerTTL=2, storage requirement is 1.5 * TTL at the expense of 3 reads per trace ID read. + partitionsPerTTL = 1 + + // reservedKeyPrefix is the prefix of internal keys used by StorageManager + reservedKeyPrefix byte = '~' + + // partitionerMetaKey is the key used to store partitioner metadata, e.g. last partition ID, in decision DB. + partitionerMetaKey = string(reservedKeyPrefix) + "partitioner" + + // diskUsageFetchInterval is how often disk usage is fetched which is equivalent to how long disk usage is cached. + diskUsageFetchInterval = 1 * time.Second +) + +type StorageManagerOptions func(*StorageManager) + +func WithCodec(codec Codec) StorageManagerOptions { + return func(sm *StorageManager) { + sm.codec = codec + } +} + +func WithMeterProvider(mp metric.MeterProvider) StorageManagerOptions { + return func(sm *StorageManager) { + sm.meterProvider = mp + } +} + +// StorageManager encapsulates pebble.DB. +// It assumes exclusive access to pebble DB at storageDir. +type StorageManager struct { + storageDir string + logger *logp.Logger + + eventDB *pebble.DB + decisionDB *pebble.DB + eventStorage *Storage + decisionStorage *Storage + + partitioner *Partitioner + + storageLimit atomic.Uint64 + + codec Codec + + // subscriberPosMu protects the subscriber file from concurrent RW. + subscriberPosMu sync.Mutex + + // cachedDiskUsage is a cached result of DiskUsage + cachedDiskUsage atomic.Uint64 + + // runCh acts as a mutex to ensure only 1 Run is actively running per StorageManager. + // as it is possible that 2 separate Run are created by 2 TBS processors during a hot reload. + runCh chan struct{} + + // meterProvider is the OTel meter provider + meterProvider metric.MeterProvider + + metricRegistration metric.Registration +} + +// NewStorageManager returns a new StorageManager with pebble DB at storageDir. +func NewStorageManager(storageDir string, opts ...StorageManagerOptions) (*StorageManager, error) { + sm := &StorageManager{ + storageDir: storageDir, + runCh: make(chan struct{}, 1), + logger: logp.NewLogger(logs.Sampling), + codec: ProtobufCodec{}, + } + for _, opt := range opts { + opt(sm) + } + + if sm.meterProvider != nil { + meter := sm.meterProvider.Meter("github.com/elastic/apm-server/x-pack/apm-server/sampling/eventstorage") + lsmSizeGauge, _ := meter.Int64ObservableGauge("apm-server.sampling.tail.storage.lsm_size") + valueLogSizeGauge, _ := meter.Int64ObservableGauge("apm-server.sampling.tail.storage.value_log_size") + + sm.metricRegistration, _ = meter.RegisterCallback(func(ctx context.Context, o metric.Observer) error { + lsmSize, valueLogSize := sm.Size() + o.ObserveInt64(lsmSizeGauge, lsmSize) + o.ObserveInt64(valueLogSizeGauge, valueLogSize) + return nil + }, lsmSizeGauge, valueLogSizeGauge) + } + + if err := sm.reset(); err != nil { + return nil, fmt.Errorf("storage manager reset error: %w", err) + } + + return sm, nil +} + +// reset initializes db and storage. +func (sm *StorageManager) reset() error { + eventDB, err := OpenEventPebble(sm.storageDir) + if err != nil { + return fmt.Errorf("open event db error: %w", err) + } + sm.eventDB = eventDB + + decisionDB, err := OpenDecisionPebble(sm.storageDir) + if err != nil { + return fmt.Errorf("open decision db error: %w", err) + } + sm.decisionDB = decisionDB + + // Only recreate partitioner on initial create + if sm.partitioner == nil { + var currentPID int + if currentPID, err = sm.loadPartitionID(); err != nil { + sm.logger.With(logp.Error(err)).Warn("failed to load partition ID, using 0 instead") + } + // We need to keep an extra partition as buffer to respect the TTL, + // as the moving window needs to cover at least TTL at all times, + // where the moving window is defined as: + // all active partitions excluding current partition + duration since the start of current partition + activePartitions := partitionsPerTTL + 1 + sm.partitioner = NewPartitioner(activePartitions, currentPID) + } + + sm.eventStorage = New(sm.eventDB, sm.partitioner, sm.codec) + sm.decisionStorage = New(sm.decisionDB, sm.partitioner, sm.codec) + + sm.updateDiskUsage() + + return nil +} + +type partitionerMeta struct { + ID int `json:"id"` +} + +// loadPartitionID loads the last saved partition ID from database, +// such that partitioner resumes from where it left off before an apm-server restart. +func (sm *StorageManager) loadPartitionID() (int, error) { + item, closer, err := sm.decisionDB.Get([]byte(partitionerMetaKey)) + if errors.Is(err, pebble.ErrNotFound) { + return 0, nil + } else if err != nil { + return 0, err + } + defer closer.Close() + var pid partitionerMeta + err = json.Unmarshal(item, &pid) + return pid.ID, err +} + +// savePartitionID saves the partition ID to database to be loaded by loadPartitionID later. +func (sm *StorageManager) savePartitionID(pid int) error { + b, err := json.Marshal(partitionerMeta{ID: pid}) + if err != nil { + return fmt.Errorf("error marshaling partition ID: %w", err) + } + return sm.decisionDB.Set([]byte(partitionerMetaKey), b, pebble.NoSync) +} + +func (sm *StorageManager) Size() (lsm, vlog int64) { + // This is reporting lsm and vlog for legacy reasons. + // vlog is always 0 because pebble does not have a vlog. + // Keeping this legacy structure such that the metrics are comparable across versions, + // and we don't need to update the tooling, e.g. kibana dashboards. + // + // TODO(carsonip): Update this to report a more helpful size to monitoring, + // maybe broken down into event DB vs decision DB, and LSM tree vs WAL vs misc. + // Also remember to update + // - x-pack/apm-server/sampling/processor.go:CollectMonitoring + // - systemtest/benchtest/expvar/metrics.go + return int64(sm.DiskUsage()), 0 +} + +// DiskUsage returns the disk usage of databases in bytes. +func (sm *StorageManager) DiskUsage() uint64 { + // pebble DiskSpaceUsage overhead is not high, but it adds up when performed per-event. + return sm.cachedDiskUsage.Load() +} + +func (sm *StorageManager) updateDiskUsage() { + sm.cachedDiskUsage.Store(sm.eventDB.Metrics().DiskSpaceUsage() + sm.decisionDB.Metrics().DiskSpaceUsage()) +} + +// runDiskUsageLoop runs a loop that updates cached disk usage regularly. +func (sm *StorageManager) runDiskUsageLoop(stopping <-chan struct{}) error { + ticker := time.NewTicker(diskUsageFetchInterval) + defer ticker.Stop() + for { + select { + case <-stopping: + return nil + case <-ticker.C: + sm.updateDiskUsage() + } + } +} + +func (sm *StorageManager) StorageLimit() uint64 { + return sm.storageLimit.Load() +} + +func (sm *StorageManager) Flush() error { + return errors.Join( + wrapNonNilErr("event db flush error: %w", sm.eventDB.Flush()), + wrapNonNilErr("decision db flush error: %w", sm.decisionDB.Flush()), + ) +} + +func (sm *StorageManager) Close() error { + return sm.close() +} + +func (sm *StorageManager) close() error { + if sm.metricRegistration != nil { + if err := sm.metricRegistration.Unregister(); err != nil { + sm.logger.With(logp.Error(err)).Error("failed to unregister metric") + } + } + return errors.Join( + wrapNonNilErr("event db flush error: %w", sm.eventDB.Flush()), + wrapNonNilErr("decision db flush error: %w", sm.decisionDB.Flush()), + wrapNonNilErr("event db close error: %w", sm.eventDB.Close()), + wrapNonNilErr("decision db close error: %w", sm.decisionDB.Close()), + ) +} + +// Reload flushes out pending disk writes to disk by reloading the database. +// For testing only. +// Read writers created prior to Reload cannot be used and will need to be recreated via NewReadWriter. +func (sm *StorageManager) Reload() error { + if err := sm.close(); err != nil { + return err + } + return sm.reset() +} + +// Run has the same lifecycle as the TBS processor as opposed to StorageManager to facilitate EA hot reload. +func (sm *StorageManager) Run(stopping <-chan struct{}, ttl time.Duration, storageLimit uint64) error { + select { + case <-stopping: + return nil + case sm.runCh <- struct{}{}: + } + defer func() { + <-sm.runCh + }() + + sm.storageLimit.Store(storageLimit) + + g := errgroup.Group{} + g.Go(func() error { + return sm.runTTLGCLoop(stopping, ttl) + }) + g.Go(func() error { + return sm.runDiskUsageLoop(stopping) + }) + + return g.Wait() +} + +// runTTLGCLoop runs the TTL GC loop. +// The loop triggers a rotation on partitions at an interval based on ttl and partitionsPerTTL. +func (sm *StorageManager) runTTLGCLoop(stopping <-chan struct{}, ttl time.Duration) error { + ttlGCInterval := ttl / partitionsPerTTL + ticker := time.NewTicker(ttlGCInterval) + defer ticker.Stop() + for { + select { + case <-stopping: + return nil + case <-ticker.C: + sm.logger.Info("running TTL GC to clear expired entries and reclaim disk space") + if err := sm.RotatePartitions(); err != nil { + sm.logger.With(logp.Error(err)).Error("failed to rotate partition") + } + sm.logger.Info("finished running TTL GC") + } + } +} + +// RotatePartitions rotates the partitions to clean up TTL-expired entries. +func (sm *StorageManager) RotatePartitions() error { + newCurrentPID, newInactivePID := sm.partitioner.Rotate() + + if err := sm.savePartitionID(newCurrentPID); err != nil { + return err + } + + // No lock is needed here as the only writer to sm.partitioner is exactly this function. + lbPrefix := byte(newInactivePID) + + lb := []byte{lbPrefix} + ub := []byte{lbPrefix + 1} // Do not use % here as ub MUST BE greater than lb + + return errors.Join( + wrapNonNilErr("event db delete range error: %w", sm.eventDB.DeleteRange(lb, ub, pebble.NoSync)), + wrapNonNilErr("decision db delete range error: %w", sm.decisionDB.DeleteRange(lb, ub, pebble.NoSync)), + wrapNonNilErr("event db compact error: %w", sm.eventDB.Compact(lb, ub, false)), + wrapNonNilErr("decision db compact error: %w", sm.decisionDB.Compact(lb, ub, false)), + ) +} + +func (sm *StorageManager) ReadSubscriberPosition() ([]byte, error) { + sm.subscriberPosMu.Lock() + defer sm.subscriberPosMu.Unlock() + return os.ReadFile(filepath.Join(sm.storageDir, subscriberPositionFile)) +} + +func (sm *StorageManager) WriteSubscriberPosition(data []byte) error { + sm.subscriberPosMu.Lock() + defer sm.subscriberPosMu.Unlock() + return os.WriteFile(filepath.Join(sm.storageDir, subscriberPositionFile), data, 0644) +} + +func (sm *StorageManager) NewReadWriter() StorageLimitReadWriter { + return NewStorageLimitReadWriter(sm, SplitReadWriter{ + eventRW: sm.eventStorage.NewReadWriter(), + decisionRW: sm.decisionStorage.NewReadWriter(), + }) +} + +// wrapNonNilErr only wraps an error with format if the error is not nil. +func wrapNonNilErr(format string, err error) error { + if err == nil { + return nil + } + return fmt.Errorf(format, err) +} diff --git a/x-pack/apm-server/sampling/eventstorage/storage_manager_bench_test.go b/x-pack/apm-server/sampling/eventstorage/storage_manager_bench_test.go new file mode 100644 index 00000000000..86ebc1d5430 --- /dev/null +++ b/x-pack/apm-server/sampling/eventstorage/storage_manager_bench_test.go @@ -0,0 +1,35 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License 2.0; +// you may not use this file except in compliance with the Elastic License 2.0. + +package eventstorage_test + +import ( + "testing" + "time" + + "github.com/gofrs/uuid/v5" + "github.com/stretchr/testify/require" +) + +func BenchmarkStorageManager_DiskUsage(b *testing.B) { + stopping := make(chan struct{}) + defer close(stopping) + sm := newStorageManager(b) + go sm.Run(stopping, time.Second, 0) + rw := sm.NewReadWriter() + for i := 0; i < 1000; i++ { + traceID := uuid.Must(uuid.NewV4()).String() + txnID := uuid.Must(uuid.NewV4()).String() + txn := makeTransaction(txnID, traceID) + err := rw.WriteTraceEvent(traceID, txnID, txn) + require.NoError(b, err) + err = rw.WriteTraceSampled(traceID, true) + require.NoError(b, err) + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + _ = sm.DiskUsage() + } + b.StopTimer() +} diff --git a/x-pack/apm-server/sampling/eventstorage/storage_manager_test.go b/x-pack/apm-server/sampling/eventstorage/storage_manager_test.go new file mode 100644 index 00000000000..1145a9d8fe4 --- /dev/null +++ b/x-pack/apm-server/sampling/eventstorage/storage_manager_test.go @@ -0,0 +1,175 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License 2.0; +// you may not use this file except in compliance with the Elastic License 2.0. + +package eventstorage_test + +import ( + "testing" + "time" + + "github.com/gofrs/uuid/v5" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/elastic/apm-data/model/modelpb" + "github.com/elastic/apm-server/x-pack/apm-server/sampling/eventstorage" +) + +func newStorageManager(tb testing.TB, opts ...eventstorage.StorageManagerOptions) *eventstorage.StorageManager { + sm := newStorageManagerNoCleanup(tb, tb.TempDir(), opts...) + tb.Cleanup(func() { sm.Close() }) + return sm +} + +func newStorageManagerNoCleanup(tb testing.TB, path string, opts ...eventstorage.StorageManagerOptions) *eventstorage.StorageManager { + sm, err := eventstorage.NewStorageManager(path, opts...) + if err != nil { + tb.Fatal(err) + } + return sm +} + +func TestStorageManager_samplingDecisionTTL(t *testing.T) { + sm := newStorageManager(t) + rw := sm.NewReadWriter() + traceID := uuid.Must(uuid.NewV4()).String() + err := rw.WriteTraceSampled(traceID, true) + assert.NoError(t, err) + sampled, err := rw.IsTraceSampled(traceID) + assert.NoError(t, err) + assert.True(t, sampled) + + // after 1 TTL + err = sm.RotatePartitions() + assert.NoError(t, err) + + sampled, err = rw.IsTraceSampled(traceID) + assert.NoError(t, err) + assert.True(t, sampled) + + // after 2 TTL + err = sm.RotatePartitions() + assert.NoError(t, err) + + _, err = rw.IsTraceSampled(traceID) + assert.ErrorIs(t, err, eventstorage.ErrNotFound) + + // after 3 TTL + err = sm.RotatePartitions() + assert.NoError(t, err) + + _, err = rw.IsTraceSampled(traceID) + assert.ErrorIs(t, err, eventstorage.ErrNotFound) +} + +func TestStorageManager_eventTTL(t *testing.T) { + sm := newStorageManager(t) + rw := sm.NewReadWriter() + traceID := uuid.Must(uuid.NewV4()).String() + txnID1 := uuid.Must(uuid.NewV4()).String() + txn1 := makeTransaction(txnID1, traceID) + err := rw.WriteTraceEvent(traceID, txnID1, txn1) + assert.NoError(t, err) + + var out modelpb.Batch + err = rw.ReadTraceEvents(traceID, &out) + assert.NoError(t, err) + assert.Len(t, out, 1) + + // after 1 TTL + err = sm.RotatePartitions() + assert.NoError(t, err) + + txnID2 := uuid.Must(uuid.NewV4()).String() + txn2 := makeTransaction(txnID2, traceID) + err = rw.WriteTraceEvent(traceID, txnID2, txn2) + assert.NoError(t, err) + + out = nil + err = rw.ReadTraceEvents(traceID, &out) + assert.NoError(t, err) + assert.Equal(t, modelpb.Batch{txn2, txn1}, out) + + // after 2 TTL + err = sm.RotatePartitions() + assert.NoError(t, err) + + out = nil + err = rw.ReadTraceEvents(traceID, &out) + assert.NoError(t, err) + assert.Equal(t, modelpb.Batch{txn2}, out) + + // after 3 TTL + err = sm.RotatePartitions() + assert.NoError(t, err) + + out = nil + err = rw.ReadTraceEvents(traceID, &out) + assert.NoError(t, err) + assert.Len(t, out, 0) +} + +func TestStorageManager_partitionID(t *testing.T) { + const traceID = "foo" + tmpDir := t.TempDir() + sm := newStorageManagerNoCleanup(t, tmpDir) + + // 0 -> 1 + assert.NoError(t, sm.RotatePartitions()) + + // write to partition 1 + err := sm.NewReadWriter().WriteTraceSampled(traceID, true) + assert.NoError(t, err) + + assert.NoError(t, sm.Close()) + + // it should read directly from partition 1 on startup instead of 0 + sm = newStorageManagerNoCleanup(t, tmpDir) + defer sm.Close() + sampled, err := sm.NewReadWriter().IsTraceSampled(traceID) + assert.NoError(t, err) + assert.True(t, sampled) +} + +func TestStorageManager_DiskUsage(t *testing.T) { + stopping := make(chan struct{}) + defer close(stopping) + sm := newStorageManager(t) + go sm.Run(stopping, time.Second, 0) + old := sm.DiskUsage() + + err := sm.NewReadWriter().WriteTraceSampled("foo", true) + require.NoError(t, err) + + err = sm.Flush() + require.NoError(t, err) + + assert.Eventually(t, func() bool { + return sm.DiskUsage() > old + }, 10*time.Second, 100*time.Millisecond) + + old = sm.DiskUsage() + + err = sm.NewReadWriter().WriteTraceEvent("foo", "bar", makeTransaction("bar", "foo")) + require.NoError(t, err) + + err = sm.Flush() + require.NoError(t, err) + + assert.Eventually(t, func() bool { + return sm.DiskUsage() > old + }, 10*time.Second, 100*time.Millisecond) +} + +func TestStorageManager_Run(t *testing.T) { + done := make(chan struct{}) + stopping := make(chan struct{}) + sm := newStorageManager(t) + go func() { + assert.NoError(t, sm.Run(stopping, time.Second, 0)) + close(done) + }() + close(stopping) + <-done +} diff --git a/x-pack/apm-server/sampling/eventstorage/storage_test.go b/x-pack/apm-server/sampling/eventstorage/storage_test.go deleted file mode 100644 index e22ae7c7010..00000000000 --- a/x-pack/apm-server/sampling/eventstorage/storage_test.go +++ /dev/null @@ -1,322 +0,0 @@ -// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one -// or more contributor license agreements. Licensed under the Elastic License 2.0; -// you may not use this file except in compliance with the Elastic License 2.0. - -package eventstorage_test - -import ( - "testing" - "time" - - "github.com/dgraph-io/badger/v2" - "github.com/gofrs/uuid" - "github.com/google/go-cmp/cmp" - "github.com/google/go-cmp/cmp/cmpopts" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - "google.golang.org/protobuf/proto" - "google.golang.org/protobuf/testing/protocmp" - - "github.com/elastic/apm-data/model/modelpb" - "github.com/elastic/apm-server/x-pack/apm-server/sampling/eventstorage" -) - -func TestWriteEvents(t *testing.T) { - // Run two tests: - // - 1 transaction and 1 span - // - 1 transaction and 100 spans - // - // The latter test will cause ReadTraceEvents to implicitly call flush. - t.Run("no_flush", func(t *testing.T) { - testWriteEvents(t, 1) - }) - t.Run("implicit_flush", func(t *testing.T) { - testWriteEvents(t, 100) - }) -} - -func testWriteEvents(t *testing.T, numSpans int) { - db := newBadgerDB(t, badgerOptions) - store := eventstorage.New(db, eventstorage.ProtobufCodec{}) - readWriter := store.NewShardedReadWriter() - defer readWriter.Close() - - beforeWrite := time.Now() - traceID := uuid.Must(uuid.NewV4()).String() - transactionID := uuid.Must(uuid.NewV4()).String() - transaction := modelpb.APMEvent{ - Transaction: &modelpb.Transaction{Id: transactionID}, - } - wOpts := eventstorage.WriterOpts{ - TTL: time.Minute, - StorageLimitInBytes: 0, - } - assert.NoError(t, readWriter.WriteTraceEvent(traceID, transactionID, &transaction, wOpts)) - - var spanEvents []*modelpb.APMEvent - for i := 0; i < numSpans; i++ { - spanID := uuid.Must(uuid.NewV4()).String() - span := modelpb.APMEvent{ - Span: &modelpb.Span{Id: spanID}, - } - assert.NoError(t, readWriter.WriteTraceEvent(traceID, spanID, &span, wOpts)) - spanEvents = append(spanEvents, &span) - } - afterWrite := time.Now() - - // We can read our writes without flushing. - var batch modelpb.Batch - assert.NoError(t, readWriter.ReadTraceEvents(traceID, &batch)) - spanEvents = append(spanEvents, &transaction) - assert.Empty(t, cmp.Diff(modelpb.Batch(spanEvents), batch, - cmpopts.SortSlices(func(e1 *modelpb.APMEvent, e2 *modelpb.APMEvent) bool { - return e1.GetSpan().GetId() < e2.GetSpan().GetId() - }), - protocmp.Transform()), - ) - - // Flush in order for the writes to be visible to other readers. - assert.NoError(t, readWriter.Flush()) - - var recorded modelpb.Batch - assert.NoError(t, db.View(func(txn *badger.Txn) error { - iter := txn.NewIterator(badger.IteratorOptions{ - Prefix: []byte(traceID), - }) - defer iter.Close() - for iter.Rewind(); iter.Valid(); iter.Next() { - item := iter.Item() - expiresAt := item.ExpiresAt() - expiryTime := time.Unix(int64(expiresAt), 0) - - // The expiry time should be somewhere between when we - // started and finished writing + the TTL. The expiry time - // is recorded as seconds since the Unix epoch, hence the - // truncation. - lowerBound := beforeWrite.Add(wOpts.TTL).Truncate(time.Second) - upperBound := afterWrite.Add(wOpts.TTL).Truncate(time.Second) - assert.Condition(t, func() bool { - return !lowerBound.After(expiryTime) - }, "expiry time %s is before %s", expiryTime, lowerBound) - assert.Condition(t, func() bool { - return !expiryTime.After(upperBound) - }, "expiry time %s is after %s", expiryTime, upperBound) - - var event modelpb.APMEvent - require.Equal(t, "e", string(item.UserMeta())) - assert.NoError(t, item.Value(func(data []byte) error { - return proto.Unmarshal(data, &event) - })) - recorded = append(recorded, &event) - } - return nil - })) - assert.Empty(t, cmp.Diff(batch, recorded, protocmp.Transform())) -} - -func TestWriteTraceSampled(t *testing.T) { - db := newBadgerDB(t, badgerOptions) - store := eventstorage.New(db, eventstorage.ProtobufCodec{}) - readWriter := store.NewShardedReadWriter() - defer readWriter.Close() - wOpts := eventstorage.WriterOpts{ - TTL: time.Minute, - StorageLimitInBytes: 0, - } - - before := time.Now() - assert.NoError(t, readWriter.WriteTraceSampled("sampled_trace_id", true, wOpts)) - assert.NoError(t, readWriter.WriteTraceSampled("unsampled_trace_id", false, wOpts)) - - // We can read our writes without flushing. - isSampled, err := readWriter.IsTraceSampled("sampled_trace_id") - assert.NoError(t, err) - assert.True(t, isSampled) - - // Flush in order for the writes to be visible to other readers. - assert.NoError(t, readWriter.Flush()) - - sampled := make(map[string]bool) - assert.NoError(t, db.View(func(txn *badger.Txn) error { - iter := txn.NewIterator(badger.IteratorOptions{}) - defer iter.Close() - for iter.Rewind(); iter.Valid(); iter.Next() { - item := iter.Item() - expiresAt := item.ExpiresAt() - expiryTime := time.Unix(int64(expiresAt), 0) - assert.Condition(t, func() bool { - return !before.After(expiryTime) && !expiryTime.After(before.Add(wOpts.TTL)) - }) - - key := string(item.Key()) - switch meta := item.UserMeta(); meta { - case 's': - sampled[key] = true - case 'u': - sampled[key] = false - default: - t.Fatalf("invalid meta %q", meta) - } - assert.Zero(t, item.ValueSize()) - } - return nil - })) - assert.Equal(t, map[string]bool{ - "sampled_trace_id": true, - "unsampled_trace_id": false, - }, sampled) -} - -func TestReadTraceEvents(t *testing.T) { - db := newBadgerDB(t, badgerOptions) - store := eventstorage.New(db, eventstorage.ProtobufCodec{}) - - traceID := [...]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16} - require.NoError(t, db.Update(func(txn *badger.Txn) error { - key := append(traceID[:], ":12345678"...) - value, err := proto.Marshal(&modelpb.APMEvent{Transaction: &modelpb.Transaction{Name: "transaction"}}) - if err != nil { - return err - } - if err := txn.SetEntry(badger.NewEntry(key, value).WithMeta('e')); err != nil { - return err - } - - key = append(traceID[:], ":87654321"...) - value, err = proto.Marshal(&modelpb.APMEvent{Span: &modelpb.Span{Name: "span"}}) - if err != nil { - return err - } - if err := txn.SetEntry(badger.NewEntry(key, value).WithMeta('e')); err != nil { - return err - } - - // Write an entry with the trace ID as a prefix, but with no - // proceeding colon, causing it to be ignored. - key = append(traceID[:], "nocolon"...) - value = []byte(`not-protobuf`) - if err := txn.SetEntry(badger.NewEntry(key, value).WithMeta('e')); err != nil { - return err - } - - // Write an entry with an unknown meta value. It will be ignored. - key = append(traceID[:], ":11111111"...) - value = []byte(`not-protobuf`) - if err := txn.SetEntry(badger.NewEntry(key, value).WithMeta('?')); err != nil { - return err - } - return nil - })) - - reader := store.NewShardedReadWriter() - defer reader.Close() - - var events modelpb.Batch - assert.NoError(t, reader.ReadTraceEvents(string(traceID[:]), &events)) - assert.Empty(t, cmp.Diff(modelpb.Batch{ - {Transaction: &modelpb.Transaction{Name: "transaction"}}, - {Span: &modelpb.Span{Name: "span"}}, - }, events, protocmp.Transform())) -} - -func TestReadTraceEventsDecodeError(t *testing.T) { - db := newBadgerDB(t, badgerOptions) - store := eventstorage.New(db, eventstorage.ProtobufCodec{}) - - traceID := [...]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16} - require.NoError(t, db.Update(func(txn *badger.Txn) error { - key := append(traceID[:], ":12345678"...) - value := []byte(`wat`) - if err := txn.SetEntry(badger.NewEntry(key, value).WithMeta('e')); err != nil { - return err - } - return nil - })) - - reader := store.NewShardedReadWriter() - defer reader.Close() - - var events modelpb.Batch - err := reader.ReadTraceEvents(string(traceID[:]), &events) - assert.Error(t, err) -} - -func TestIsTraceSampled(t *testing.T) { - db := newBadgerDB(t, badgerOptions) - store := eventstorage.New(db, eventstorage.ProtobufCodec{}) - - require.NoError(t, db.Update(func(txn *badger.Txn) error { - if err := txn.SetEntry(badger.NewEntry([]byte("sampled_trace_id"), nil).WithMeta('s')); err != nil { - return err - } - if err := txn.SetEntry(badger.NewEntry([]byte("unsampled_trace_id"), nil).WithMeta('u')); err != nil { - return err - } - return nil - })) - - reader := store.NewShardedReadWriter() - defer reader.Close() - - sampled, err := reader.IsTraceSampled("sampled_trace_id") - assert.NoError(t, err) - assert.True(t, sampled) - - sampled, err = reader.IsTraceSampled("unsampled_trace_id") - assert.NoError(t, err) - assert.False(t, sampled) - - _, err = reader.IsTraceSampled("unknown_trace_id") - assert.Equal(t, err, eventstorage.ErrNotFound) -} - -func TestStorageLimit(t *testing.T) { - tempdir := t.TempDir() - opts := func() badger.Options { - opts := badgerOptions() - opts = opts.WithInMemory(false) - opts = opts.WithDir(tempdir).WithValueDir(tempdir) - return opts - } - - // Open and close the database to create a non-empty value log file, - // which will cause writes below to fail due to the storage limit being - // exceeded. We would otherwise have to rely on Badger's one minute - // timer to refresh the size. - db := newBadgerDB(t, opts) - db.Close() - db = newBadgerDB(t, opts) - - store := eventstorage.New(db, eventstorage.ProtobufCodec{}) - readWriter := store.NewReadWriter() - defer readWriter.Close() - - traceID := uuid.Must(uuid.NewV4()).String() - transactionID := uuid.Must(uuid.NewV4()).String() - transaction := modelpb.APMEvent{Transaction: &modelpb.Transaction{Id: transactionID}} - err := readWriter.WriteTraceEvent(traceID, transactionID, &transaction, eventstorage.WriterOpts{ - TTL: time.Minute, - StorageLimitInBytes: 1, - }) - assert.ErrorIs(t, err, eventstorage.ErrLimitReached) - - // Assert the stored write has been discarded. - var batch modelpb.Batch - readWriter.ReadTraceEvents(traceID, &batch) - assert.Equal(t, 0, len(batch)) -} - -func badgerOptions() badger.Options { - return badger.DefaultOptions("").WithInMemory(true).WithLogger(nil) -} - -type badgerOptionsFunc func() badger.Options - -func newBadgerDB(tb testing.TB, badgerOptions badgerOptionsFunc) *badger.DB { - db, err := badger.Open(badgerOptions()) - if err != nil { - panic(err) - } - tb.Cleanup(func() { db.Close() }) - return db -} diff --git a/x-pack/apm-server/sampling/eventstorage/storage_whitebox_test.go b/x-pack/apm-server/sampling/eventstorage/storage_whitebox_test.go deleted file mode 100644 index 7abae0980ed..00000000000 --- a/x-pack/apm-server/sampling/eventstorage/storage_whitebox_test.go +++ /dev/null @@ -1,94 +0,0 @@ -// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one -// or more contributor license agreements. Licensed under the Elastic License 2.0; -// you may not use this file except in compliance with the Elastic License 2.0. - -package eventstorage - -import ( - "testing" - "time" - - "github.com/dgraph-io/badger/v2" - "github.com/gofrs/uuid" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - - "github.com/elastic/apm-data/model/modelpb" -) - -func newReadWriter(tb testing.TB) *ReadWriter { - tempdir := tb.TempDir() - opts := badger.DefaultOptions("").WithLogger(nil) - opts = opts.WithInMemory(false) - opts = opts.WithDir(tempdir).WithValueDir(tempdir) - - db, err := badger.Open(opts) - if err != nil { - panic(err) - } - tb.Cleanup(func() { db.Close() }) - - store := New(db, ProtobufCodec{}) - readWriter := store.NewReadWriter() - tb.Cleanup(func() { readWriter.Close() }) - - return readWriter -} - -func TestDeleteTraceEvent_ErrTxnTooBig(t *testing.T) { - readWriter := newReadWriter(t) - - traceID, transactionID := writeEvent(t, readWriter) - assert.True(t, eventExists(t, readWriter, traceID, transactionID)) - - fillTxnUntilTxnTooBig(readWriter.txn) - - err := readWriter.DeleteTraceEvent(traceID, transactionID) - assert.NoError(t, err) - - assert.False(t, eventExists(t, readWriter, traceID, transactionID)) -} - -func TestWriteTraceEvent_ErrTxnTooBig(t *testing.T) { - readWriter := newReadWriter(t) - - fillTxnUntilTxnTooBig(readWriter.txn) - - traceID, transactionID := writeEvent(t, readWriter) - assert.True(t, eventExists(t, readWriter, traceID, transactionID)) -} - -func writeEvent(t *testing.T, readWriter *ReadWriter) (traceID, transactionID string) { - traceID = uuid.Must(uuid.NewV4()).String() - transactionID = uuid.Must(uuid.NewV4()).String() - transaction := modelpb.APMEvent{Transaction: &modelpb.Transaction{Id: transactionID}} - err := readWriter.WriteTraceEvent(traceID, transactionID, &transaction, WriterOpts{ - TTL: time.Minute, - StorageLimitInBytes: 0, - }) - assert.NoError(t, err) - return -} - -func eventExists(t *testing.T, readWriter *ReadWriter, traceID, transactionID string) (ok bool) { - var batch modelpb.Batch - err := readWriter.ReadTraceEvents(traceID, &batch) - require.NoError(t, err) - for _, e := range batch { - if e.GetTransaction().GetId() == transactionID { - ok = true - } - } - return -} - -func fillTxnUntilTxnTooBig(txn *badger.Txn) { - var err error - for { - if err == badger.ErrTxnTooBig { - break - } - entry := badger.NewEntry([]byte{0}, []byte{}) - err = txn.SetEntry(entry) - } -} diff --git a/x-pack/apm-server/sampling/groups.go b/x-pack/apm-server/sampling/groups.go index c852ffa36d3..33bc8511f7f 100644 --- a/x-pack/apm-server/sampling/groups.go +++ b/x-pack/apm-server/sampling/groups.go @@ -5,12 +5,15 @@ package sampling import ( + "context" "errors" "math" "math/rand" "sync" "time" + "go.opentelemetry.io/otel/metric" + "github.com/elastic/apm-data/model/modelpb" ) @@ -32,6 +35,10 @@ type traceGroups struct { // be created, and events may be dropped. maxDynamicServiceGroups int + // numDynamicServiceGroupsCounter is used for reporting the current number + // of dynamic service groups. + numDynamicServiceGroupsCounter metric.Int64UpDownCounter + mu sync.RWMutex policyGroups []policyGroup numDynamicServiceGroups int @@ -60,14 +67,17 @@ func (g *policyGroup) match(transactionEvent *modelpb.APMEvent) bool { } func newTraceGroups( + meter metric.Meter, policies []Policy, maxDynamicServiceGroups int, ingestRateDecayFactor float64, ) *traceGroups { + numDynamicServiceGroupsCounter, _ := meter.Int64UpDownCounter("apm-server.sampling.tail.dynamic_service_groups") groups := &traceGroups{ - ingestRateDecayFactor: ingestRateDecayFactor, - maxDynamicServiceGroups: maxDynamicServiceGroups, - policyGroups: make([]policyGroup, len(policies)), + ingestRateDecayFactor: ingestRateDecayFactor, + maxDynamicServiceGroups: maxDynamicServiceGroups, + numDynamicServiceGroupsCounter: numDynamicServiceGroupsCounter, + policyGroups: make([]policyGroup, len(policies)), } for i, policy := range policies { pg := policyGroup{policy: policy} @@ -150,6 +160,7 @@ func (g *traceGroups) getTraceGroup(transactionEvent *modelpb.APMEvent) (*traceG return nil, errTooManyTraceGroups } g.numDynamicServiceGroups++ + g.numDynamicServiceGroupsCounter.Add(context.Background(), 1) group = newTraceGroup(pg.policy.SampleRate) pg.dynamic[transactionEvent.GetService().GetName()] = group } @@ -183,12 +194,12 @@ func (g *traceGroups) finalizeSampledTraces(traceIDs []string) []string { maxDynamicServiceGroupsReached := g.numDynamicServiceGroups == g.maxDynamicServiceGroups for _, pg := range g.policyGroups { if pg.g != nil { - traceIDs = pg.g.finalizeSampledTraces(traceIDs, g.ingestRateDecayFactor) + _, traceIDs = pg.g.finalizeSampledTraces(traceIDs, g.ingestRateDecayFactor) continue } for serviceName, group := range pg.dynamic { - total := group.total - traceIDs = group.finalizeSampledTraces(traceIDs, g.ingestRateDecayFactor) + var total int + total, traceIDs = group.finalizeSampledTraces(traceIDs, g.ingestRateDecayFactor) if (maxDynamicServiceGroupsReached || total == 0) && group.reservoir.Size() == minReservoirSize { g.numDynamicServiceGroups-- delete(pg.dynamic, serviceName) @@ -199,12 +210,14 @@ func (g *traceGroups) finalizeSampledTraces(traceIDs []string) []string { } // finalizeSampledTraces appends the group's current trace IDs to traceIDs, and -// returns the extended slice. On return the groups' sampling reservoirs will be -// reset. -func (g *traceGroup) finalizeSampledTraces(traceIDs []string, ingestRateDecayFactor float64) []string { +// returns total of the group and the extended slice. +// On return the groups' sampling reservoirs will be reset. +func (g *traceGroup) finalizeSampledTraces(traceIDs []string, ingestRateDecayFactor float64) (int, []string) { g.mu.Lock() defer g.mu.Unlock() + oldTotal := g.total + if g.ingestRate == 0 { g.ingestRate = float64(g.total) } else { @@ -230,5 +243,5 @@ func (g *traceGroup) finalizeSampledTraces(traceIDs []string, ingestRateDecayFac } g.reservoir.Reset() g.reservoir.Resize(newReservoirSize) - return traceIDs + return oldTotal, traceIDs } diff --git a/x-pack/apm-server/sampling/groups_test.go b/x-pack/apm-server/sampling/groups_test.go index 10fa7e87322..88238bd5577 100644 --- a/x-pack/apm-server/sampling/groups_test.go +++ b/x-pack/apm-server/sampling/groups_test.go @@ -6,12 +6,14 @@ package sampling import ( "fmt" + "sync" "testing" "time" - "github.com/gofrs/uuid" + "github.com/gofrs/uuid/v5" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "go.opentelemetry.io/otel/metric/noop" "github.com/elastic/apm-data/model/modelpb" ) @@ -63,7 +65,7 @@ func TestTraceGroupsPolicies(t *testing.T) { policy.ServiceName = "" policies = append(policies, policy) } - groups := newTraceGroups(policies, 1000, 1.0) + groups := newTraceGroups(noop.Meter{}, policies, 1000, 1.0) assertSampleRate := func(sampleRate float64, serviceName, serviceEnvironment, traceOutcome, traceName string) { tx := makeTransaction(serviceName, serviceEnvironment, traceOutcome, traceName) @@ -91,7 +93,7 @@ func TestTraceGroupsMax(t *testing.T) { ingestRateCoefficient = 1.0 ) policies := []Policy{{SampleRate: 1.0}} - groups := newTraceGroups(policies, maxDynamicServices, ingestRateCoefficient) + groups := newTraceGroups(noop.Meter{}, policies, maxDynamicServices, ingestRateCoefficient) for i := 0; i < maxDynamicServices; i++ { serviceName := fmt.Sprintf("service_group_%d", i) @@ -130,7 +132,7 @@ func TestTraceGroupReservoirResize(t *testing.T) { ingestRateCoefficient = 0.75 ) policies := []Policy{{SampleRate: 0.2}} - groups := newTraceGroups(policies, maxDynamicServices, ingestRateCoefficient) + groups := newTraceGroups(noop.Meter{}, policies, maxDynamicServices, ingestRateCoefficient) sendTransactions := func(n int) { for i := 0; i < n; i++ { @@ -172,7 +174,7 @@ func TestTraceGroupReservoirResizeMinimum(t *testing.T) { ingestRateCoefficient = 1.0 ) policies := []Policy{{SampleRate: 0.1}} - groups := newTraceGroups(policies, maxDynamicServices, ingestRateCoefficient) + groups := newTraceGroups(noop.Meter{}, policies, maxDynamicServices, ingestRateCoefficient) sendTransactions := func(n int) { for i := 0; i < n; i++ { @@ -208,7 +210,7 @@ func TestTraceGroupsRemoval(t *testing.T) { {SampleRate: 0.5}, {PolicyCriteria: PolicyCriteria{ServiceName: "defined_later"}, SampleRate: 0.5}, } - groups := newTraceGroups(policies, maxDynamicServices, ingestRateCoefficient) + groups := newTraceGroups(noop.Meter{}, policies, maxDynamicServices, ingestRateCoefficient) for i := 0; i < 10000; i++ { _, err := groups.sampleTrace(&modelpb.APMEvent{ @@ -257,13 +259,49 @@ func TestTraceGroupsRemoval(t *testing.T) { assert.NoError(t, err) } +func TestTraceGroupsRemovalConcurrent(t *testing.T) { + // Ensure that trace groups removal does not race with sampleTrace + const ( + maxDynamicServices = 2 + ingestRateCoefficient = 1.0 + ) + policies := []Policy{ + {SampleRate: 1}, + } + groups := newTraceGroups(noop.Meter{}, policies, maxDynamicServices, ingestRateCoefficient) + + wg := sync.WaitGroup{} + wg.Add(2) + // create a dynamic group first + _, err := groups.sampleTrace(&modelpb.APMEvent{ + Service: &modelpb.Service{Name: "many"}, + Transaction: &modelpb.Transaction{Type: "type"}, + }) + assert.NoError(t, err) + go func() { + for i := 0; i < 10; i++ { + _, err := groups.sampleTrace(&modelpb.APMEvent{ + Service: &modelpb.Service{Name: "many"}, + Transaction: &modelpb.Transaction{Type: "type"}, + }) + assert.NoError(t, err) + } + wg.Done() + }() + go func() { + groups.finalizeSampledTraces(nil) + wg.Done() + }() + wg.Wait() +} + func BenchmarkTraceGroups(b *testing.B) { const ( maxDynamicServices = 1000 ingestRateCoefficient = 1.0 ) policies := []Policy{{SampleRate: 1.0}} - groups := newTraceGroups(policies, maxDynamicServices, ingestRateCoefficient) + groups := newTraceGroups(noop.Meter{}, policies, maxDynamicServices, ingestRateCoefficient) b.RunParallel(func(pb *testing.PB) { // Transaction identifiers are different for each goroutine, simulating diff --git a/x-pack/apm-server/sampling/processor.go b/x-pack/apm-server/sampling/processor.go index 82dc2df59aa..7a149ef2cea 100644 --- a/x-pack/apm-server/sampling/processor.go +++ b/x-pack/apm-server/sampling/processor.go @@ -9,13 +9,11 @@ import ( "encoding/json" "fmt" "os" - "path/filepath" "sync" - "sync/atomic" "time" - "github.com/dgraph-io/badger/v2" "github.com/pkg/errors" + "go.opentelemetry.io/otel/metric" "golang.org/x/sync/errgroup" "github.com/elastic/apm-data/model/modelpb" @@ -23,14 +21,9 @@ import ( "github.com/elastic/apm-server/x-pack/apm-server/sampling/eventstorage" "github.com/elastic/apm-server/x-pack/apm-server/sampling/pubsub" "github.com/elastic/elastic-agent-libs/logp" - "github.com/elastic/elastic-agent-libs/monitoring" ) const ( - // subscriberPositionFile holds the file name used for persisting - // the subscriber position across server restarts. - subscriberPositionFile = "subscriber_position.json" - // loggerRateLimit is the maximum frequency at which "too many groups" and // "write failure" log messages are logged. loggerRateLimit = time.Minute @@ -47,23 +40,21 @@ type Processor struct { rateLimitedLogger *logp.Logger groups *traceGroups - eventStore *wrappedRW - eventMetrics *eventMetrics // heap-allocated for 64-bit alignment + eventStore eventstorage.RW + eventMetrics eventMetrics stopMu sync.Mutex stopping chan struct{} stopped chan struct{} - - indexOnWriteFailure bool } type eventMetrics struct { - processed int64 - dropped int64 - stored int64 - sampled int64 - headUnsampled int64 - failedWrites int64 + processed metric.Int64Counter + dropped metric.Int64Counter + stored metric.Int64Counter + sampled metric.Int64Counter + headUnsampled metric.Int64Counter + failedWrites metric.Int64Counter } // NewProcessor returns a new Processor, for tail-sampling trace events. @@ -72,59 +63,27 @@ func NewProcessor(config Config) (*Processor, error) { return nil, errors.Wrap(err, "invalid tail-sampling config") } + meter := config.MeterProvider.Meter("github.com/elastic/apm-server/x-pack/apm-server/sampling") + logger := logp.NewLogger(logs.Sampling) p := &Processor{ config: config, logger: logger, rateLimitedLogger: logger.WithOptions(logs.WithRateLimit(loggerRateLimit)), - groups: newTraceGroups(config.Policies, config.MaxDynamicServices, config.IngestRateDecayFactor), - eventStore: newWrappedRW(config.Storage, config.TTL, int64(config.StorageLimit)), - eventMetrics: &eventMetrics{}, + groups: newTraceGroups(meter, config.Policies, config.MaxDynamicServices, config.IngestRateDecayFactor), + eventStore: config.Storage, stopping: make(chan struct{}), stopped: make(chan struct{}), - // NOTE(marclop) This behavior should be configurable so users who - // rely on tail sampling for cost cutting, can discard events once - // the disk is full. - // Index all traces when the storage limit is reached. - indexOnWriteFailure: true, } - return p, nil -} -// CollectMonitoring may be called to collect monitoring metrics related to -// tail-sampling. It is intended to be used with libbeat/monitoring.NewFunc. -// -// The metrics should be added to the "apm-server.sampling.tail" registry. -func (p *Processor) CollectMonitoring(_ monitoring.Mode, V monitoring.Visitor) { - V.OnRegistryStart() - defer V.OnRegistryFinished() + p.eventMetrics.processed, _ = meter.Int64Counter("apm-server.sampling.tail.events.processed") + p.eventMetrics.dropped, _ = meter.Int64Counter("apm-server.sampling.tail.events.dropped") + p.eventMetrics.stored, _ = meter.Int64Counter("apm-server.sampling.tail.events.stored") + p.eventMetrics.sampled, _ = meter.Int64Counter("apm-server.sampling.tail.events.sampled") + p.eventMetrics.headUnsampled, _ = meter.Int64Counter("apm-server.sampling.tail.events.head_unsampled") + p.eventMetrics.failedWrites, _ = meter.Int64Counter("apm-server.sampling.tail.events.failed_writes") - // TODO(axw) it might be nice to also report some metrics about: - // - // - The time between receiving events and when they are indexed. - // This could be accomplished by recording the time when the - // payload was received in the ECS field `event.created`. The - // final metric would ideally be a distribution, which is not - // currently an option in libbeat/monitoring. - - p.groups.mu.RLock() - numDynamicGroups := p.groups.numDynamicServiceGroups - p.groups.mu.RUnlock() - monitoring.ReportInt(V, "dynamic_service_groups", int64(numDynamicGroups)) - - monitoring.ReportNamespace(V, "storage", func() { - lsmSize, valueLogSize := p.config.DB.Size() - monitoring.ReportInt(V, "lsm_size", int64(lsmSize)) - monitoring.ReportInt(V, "value_log_size", int64(valueLogSize)) - }) - monitoring.ReportNamespace(V, "events", func() { - monitoring.ReportInt(V, "processed", atomic.LoadInt64(&p.eventMetrics.processed)) - monitoring.ReportInt(V, "dropped", atomic.LoadInt64(&p.eventMetrics.dropped)) - monitoring.ReportInt(V, "stored", atomic.LoadInt64(&p.eventMetrics.stored)) - monitoring.ReportInt(V, "sampled", atomic.LoadInt64(&p.eventMetrics.sampled)) - monitoring.ReportInt(V, "head_unsampled", atomic.LoadInt64(&p.eventMetrics.headUnsampled)) - monitoring.ReportInt(V, "failed_writes", atomic.LoadInt64(&p.eventMetrics.failedWrites)) - }) + return p, nil } // ProcessBatch tail-samples transactions and spans. @@ -146,11 +105,11 @@ func (p *Processor) ProcessBatch(ctx context.Context, batch *modelpb.Batch) erro var err error switch event.Type() { case modelpb.TransactionEventType: - atomic.AddInt64(&p.eventMetrics.processed, 1) - report, stored, err = p.processTransaction(event) + p.eventMetrics.processed.Add(ctx, 1) + report, stored, err = p.processTransaction(ctx, event) case modelpb.SpanEventType: - atomic.AddInt64(&p.eventMetrics.processed, 1) - report, stored, err = p.processSpan(event) + p.eventMetrics.processed.Add(ctx, 1) + report, stored, err = p.processSpan(ctx, event) default: continue } @@ -160,12 +119,12 @@ func (p *Processor) ProcessBatch(ctx context.Context, batch *modelpb.Batch) erro if err != nil { failed = true stored = false - if p.indexOnWriteFailure { - report = true - p.rateLimitedLogger.Info("processing trace failed, indexing by default") - } else { + if p.config.DiscardOnWriteFailure { report = false p.rateLimitedLogger.Info("processing trace failed, discarding by default") + } else { + report = true + p.rateLimitedLogger.Info("processing trace failed, indexing by default") } } @@ -177,18 +136,18 @@ func (p *Processor) ProcessBatch(ctx context.Context, batch *modelpb.Batch) erro i-- } - p.updateProcessorMetrics(report, stored, failed) + p.updateProcessorMetrics(ctx, report, stored, failed) } *batch = events return nil } -func (p *Processor) updateProcessorMetrics(report, stored, failedWrite bool) { +func (p *Processor) updateProcessorMetrics(ctx context.Context, report, stored, failedWrite bool) { if failedWrite { - atomic.AddInt64(&p.eventMetrics.failedWrites, 1) + p.eventMetrics.failedWrites.Add(ctx, 1) } if stored { - atomic.AddInt64(&p.eventMetrics.stored, 1) + p.eventMetrics.stored.Add(ctx, 1) } else if !report { // We only increment the "dropped" counter if // we neither reported nor stored the event, so @@ -199,15 +158,15 @@ func (p *Processor) updateProcessorMetrics(report, stored, failedWrite bool) { // The counter does not include events that are // implicitly dropped, i.e. stored and never // indexed. - atomic.AddInt64(&p.eventMetrics.dropped, 1) + p.eventMetrics.dropped.Add(ctx, 1) } } -func (p *Processor) processTransaction(event *modelpb.APMEvent) (report, stored bool, _ error) { +func (p *Processor) processTransaction(ctx context.Context, event *modelpb.APMEvent) (report, stored bool, _ error) { if !event.Transaction.Sampled { // (Head-based) unsampled transactions are passed through // by the tail sampler. - atomic.AddInt64(&p.eventMetrics.headUnsampled, 1) + p.eventMetrics.headUnsampled.Add(ctx, 1) return true, false, nil } @@ -218,7 +177,7 @@ func (p *Processor) processTransaction(event *modelpb.APMEvent) (report, stored // if it was sampled. report := traceSampled if report { - atomic.AddInt64(&p.eventMetrics.sampled, 1) + p.eventMetrics.sampled.Add(ctx, 1) } return report, false, nil case eventstorage.ErrNotFound: @@ -270,7 +229,7 @@ sampling policies without service name specified. return false, true, p.eventStore.WriteTraceEvent(event.Trace.Id, event.Transaction.Id, event) } -func (p *Processor) processSpan(event *modelpb.APMEvent) (report, stored bool, _ error) { +func (p *Processor) processSpan(ctx context.Context, event *modelpb.APMEvent) (report, stored bool, _ error) { traceSampled, err := p.eventStore.IsTraceSampled(event.Trace.Id) if err != nil { if err == eventstorage.ErrNotFound { @@ -281,13 +240,14 @@ func (p *Processor) processSpan(event *modelpb.APMEvent) (report, stored bool, _ } // Tail-sampling decision has been made, report or drop the event. if traceSampled { - atomic.AddInt64(&p.eventMetrics.sampled, 1) + p.eventMetrics.sampled.Add(ctx, 1) } return traceSampled, false, nil } -// Stop stops the processor, flushing event storage. Note that the underlying -// badger.DB must be closed independently to ensure writes are synced to disk. +// Stop stops the processor. +// Note that the underlying StorageManager must be closed independently +// to ensure writes are synced to disk. func (p *Processor) Stop(ctx context.Context) error { p.stopMu.Lock() select { @@ -306,8 +266,7 @@ func (p *Processor) Stop(ctx context.Context) error { case <-p.stopped: } - // Flush event store and the underlying read writers - return p.eventStore.Flush() + return nil } // Run runs the tail-sampling processor. This method is responsible for: @@ -338,7 +297,7 @@ func (p *Processor) Run() error { bulkIndexerFlushInterval = p.config.FlushInterval } - initialSubscriberPosition, err := readSubscriberPosition(p.logger, p.config.StorageDir) + initialSubscriberPosition, err := readSubscriberPosition(p.logger, p.config.DB) if err != nil { return err } @@ -377,7 +336,7 @@ func (p *Processor) Run() error { time.AfterFunc(shutdownGracePeriod, cancelGracefulContext) return context.Canceled case pos := <-subscriberPositions: - if err := writeSubscriberPosition(p.config.StorageDir, pos); err != nil { + if err := writeSubscriberPosition(p.config.DB, pos); err != nil { p.rateLimitedLogger.With(logp.Error(err)).With(logp.Reflect("position", pos)).Warn( "failed to write subscriber position: %s", err, ) @@ -386,32 +345,13 @@ func (p *Processor) Run() error { } }) g.Go(func() error { - // This goroutine is responsible for periodically garbage - // collecting the Badger value log, using the recommended - // discard ratio of 0.5. - ticker := time.NewTicker(p.config.StorageGCInterval) - defer ticker.Stop() - for { - select { - case <-p.stopping: - return nil - case <-ticker.C: - const discardRatio = 0.5 - var err error - for err == nil { - // Keep garbage collecting until there are no more rewrites, - // or garbage collection fails. - err = p.config.DB.RunValueLogGC(discardRatio) - } - if err != nil && err != badger.ErrNoRewrite { - return err - } - } - } + return p.config.DB.Run(p.stopping, p.config.TTL, p.config.StorageLimit) }) g.Go(func() error { // Subscribe to remotely sampled trace IDs. This is cancelled immediately when - // Stop is called. The next subscriber will pick up from the previous position. + // Stop is called. But it is possible that both old and new subscriber goroutines + // run concurrently, before the old one eventually receives the Stop call. + // The next subscriber will pick up from the previous position. defer close(remoteSampledTraceIDs) defer close(subscriberPositions) ctx, cancel := context.WithCancel(context.Background()) @@ -528,6 +468,10 @@ func (p *Processor) Run() error { // deleted. We delete events from local storage so // we don't publish duplicates; delivery is therefore // at-most-once, not guaranteed. + // + // TODO(carsonip): pebble supports range deletes and may be better than + // deleting events separately, but as we do not use transactions, it is + // possible to race and delete something that is not read. for _, event := range events { switch event.Type() { case modelpb.TransactionEventType: @@ -541,7 +485,7 @@ func (p *Processor) Run() error { } } } - atomic.AddInt64(&p.eventMetrics.sampled, int64(len(events))) + p.eventMetrics.sampled.Add(gracefulContext, int64(len(events))) if err := p.config.BatchProcessor.ProcessBatch(gracefulContext, &events); err != nil { p.logger.With(logp.Error(err)).Warn("failed to report events") } @@ -558,9 +502,9 @@ func (p *Processor) Run() error { return nil } -func readSubscriberPosition(logger *logp.Logger, storageDir string) (pubsub.SubscriberPosition, error) { +func readSubscriberPosition(logger *logp.Logger, s *eventstorage.StorageManager) (pubsub.SubscriberPosition, error) { var pos pubsub.SubscriberPosition - data, err := os.ReadFile(filepath.Join(storageDir, subscriberPositionFile)) + data, err := s.ReadSubscriberPosition() if errors.Is(err, os.ErrNotExist) { return pos, nil } else if err != nil { @@ -574,12 +518,13 @@ func readSubscriberPosition(logger *logp.Logger, storageDir string) (pubsub.Subs return pos, nil } -func writeSubscriberPosition(storageDir string, pos pubsub.SubscriberPosition) error { +func writeSubscriberPosition(s *eventstorage.StorageManager, pos pubsub.SubscriberPosition) error { data, err := json.Marshal(pos) if err != nil { return err } - return os.WriteFile(filepath.Join(storageDir, subscriberPositionFile), data, 0644) + + return s.WriteSubscriberPosition(data) } func sendTraceIDs(ctx context.Context, out chan<- string, traceIDs []string) error { @@ -592,61 +537,3 @@ func sendTraceIDs(ctx context.Context, out chan<- string, traceIDs []string) err } return nil } - -const ( - storageLimitThreshold = 0.90 // Allow 90% of the quota to be used. -) - -// wrappedRW wraps configurable write options for global ShardedReadWriter -type wrappedRW struct { - rw *eventstorage.ShardedReadWriter - writerOpts eventstorage.WriterOpts -} - -// Stored entries expire after ttl. -// The amount of storage that can be consumed can be limited by passing in a -// limit value greater than zero. The hard limit on storage is set to 90% of -// the limit to account for delay in the size reporting by badger. -// https://github.com/dgraph-io/badger/blob/82b00f27e3827022082225221ae05c03f0d37620/db.go#L1302-L1319. -func newWrappedRW(rw *eventstorage.ShardedReadWriter, ttl time.Duration, limit int64) *wrappedRW { - if limit > 1 { - limit = int64(float64(limit) * storageLimitThreshold) - } - return &wrappedRW{ - rw: rw, - writerOpts: eventstorage.WriterOpts{ - TTL: ttl, - StorageLimitInBytes: limit, - }, - } -} - -// ReadTraceEvents calls ShardedReadWriter.ReadTraceEvents -func (s *wrappedRW) ReadTraceEvents(traceID string, out *modelpb.Batch) error { - return s.rw.ReadTraceEvents(traceID, out) -} - -// WriteTraceEvents calls ShardedReadWriter.WriteTraceEvents using the configured WriterOpts -func (s *wrappedRW) WriteTraceEvent(traceID, id string, event *modelpb.APMEvent) error { - return s.rw.WriteTraceEvent(traceID, id, event, s.writerOpts) -} - -// WriteTraceSampled calls ShardedReadWriter.WriteTraceSampled using the configured WriterOpts -func (s *wrappedRW) WriteTraceSampled(traceID string, sampled bool) error { - return s.rw.WriteTraceSampled(traceID, sampled, s.writerOpts) -} - -// IsTraceSampled calls ShardedReadWriter.IsTraceSampled -func (s *wrappedRW) IsTraceSampled(traceID string) (bool, error) { - return s.rw.IsTraceSampled(traceID) -} - -// DeleteTraceEvent calls ShardedReadWriter.DeleteTraceEvent -func (s *wrappedRW) DeleteTraceEvent(traceID, id string) error { - return s.rw.DeleteTraceEvent(traceID, id) -} - -// Flush calls ShardedReadWriter.Flush -func (s *wrappedRW) Flush() error { - return s.rw.Flush() -} diff --git a/x-pack/apm-server/sampling/processor_bench_test.go b/x-pack/apm-server/sampling/processor_bench_test.go index 196a62f0cd4..4ae725bcd2a 100644 --- a/x-pack/apm-server/sampling/processor_bench_test.go +++ b/x-pack/apm-server/sampling/processor_bench_test.go @@ -20,7 +20,7 @@ import ( ) func BenchmarkProcess(b *testing.B) { - processor, err := sampling.NewProcessor(newTempdirConfig(b)) + processor, err := sampling.NewProcessor(newTempdirConfig(b).Config) require.NoError(b, err) go processor.Run() b.Cleanup(func() { processor.Stop(context.Background()) }) diff --git a/x-pack/apm-server/sampling/processor_test.go b/x-pack/apm-server/sampling/processor_test.go index f17500da501..fdc1e0d578b 100644 --- a/x-pack/apm-server/sampling/processor_test.go +++ b/x-pack/apm-server/sampling/processor_test.go @@ -9,30 +9,28 @@ import ( "fmt" "math/rand" "os" - "path" "path/filepath" - "runtime" - "sort" - "strings" "testing" "time" - "github.com/gofrs/uuid" + "github.com/gofrs/uuid/v5" "github.com/google/go-cmp/cmp" "github.com/pkg/errors" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + sdkmetric "go.opentelemetry.io/otel/sdk/metric" + "go.opentelemetry.io/otel/sdk/metric/metricdata" "google.golang.org/protobuf/testing/protocmp" "github.com/elastic/apm-data/model/modelpb" + "github.com/elastic/apm-server/internal/beater/monitoringtest" "github.com/elastic/apm-server/x-pack/apm-server/sampling" "github.com/elastic/apm-server/x-pack/apm-server/sampling/eventstorage" "github.com/elastic/apm-server/x-pack/apm-server/sampling/pubsub/pubsubtest" - "github.com/elastic/elastic-agent-libs/monitoring" ) func TestProcessUnsampled(t *testing.T) { - processor, err := sampling.NewProcessor(newTempdirConfig(t)) + processor, err := sampling.NewProcessor(newTempdirConfig(t).Config) require.NoError(t, err) go processor.Run() defer processor.Stop(context.Background()) @@ -56,34 +54,24 @@ func TestProcessUnsampled(t *testing.T) { } func TestProcessAlreadyTailSampled(t *testing.T) { - config := newTempdirConfig(t) + tempdirConfig := newTempdirConfig(t) + config := tempdirConfig.Config // Seed event storage with a tail-sampling decisions, to show that // subsequent events in the trace will be reported immediately. trace1 := modelpb.Trace{Id: "0102030405060708090a0b0c0d0e0f10"} trace2 := modelpb.Trace{Id: "0102030405060708090a0b0c0d0e0f11"} - storage := eventstorage.New(config.DB, eventstorage.ProtobufCodec{}) - writer := storage.NewReadWriter() - wOpts := eventstorage.WriterOpts{ - TTL: time.Minute, - StorageLimitInBytes: 0, - } - assert.NoError(t, writer.WriteTraceSampled(trace1.Id, true, wOpts)) - assert.NoError(t, writer.Flush()) - writer.Close() - - wOpts.TTL = -1 // expire immediately - storage = eventstorage.New(config.DB, eventstorage.ProtobufCodec{}) - writer = storage.NewReadWriter() - assert.NoError(t, writer.WriteTraceSampled(trace2.Id, true, wOpts)) - assert.NoError(t, writer.Flush()) - writer.Close() - - // Badger transactions created globally before committing the above writes - // will not see them due to SSI (Serializable Snapshot Isolation). Flush - // the storage so that new transactions are created for the underlying - // writer shards that can list all the events committed so far. - require.NoError(t, config.Storage.Flush()) + writer := config.DB.NewReadWriter() + assert.NoError(t, writer.WriteTraceSampled(trace2.Id, true)) + + // simulate 2 TTL + assert.NoError(t, config.DB.RotatePartitions()) + assert.NoError(t, config.DB.RotatePartitions()) + + writer = config.DB.NewReadWriter() + assert.NoError(t, writer.WriteTraceSampled(trace1.Id, true)) + + require.NoError(t, config.DB.Flush()) processor, err := sampling.NewProcessor(config) require.NoError(t, err) @@ -130,20 +118,16 @@ func TestProcessAlreadyTailSampled(t *testing.T) { // they were received after the trace sampling entry expired. assert.Equal(t, modelpb.Batch{&transaction1, &span1}, batch) - expectedMonitoring := monitoring.MakeFlatSnapshot() - expectedMonitoring.Ints["sampling.events.processed"] = 4 - expectedMonitoring.Ints["sampling.events.head_unsampled"] = 0 - expectedMonitoring.Ints["sampling.events.stored"] = 2 - expectedMonitoring.Ints["sampling.events.sampled"] = 2 - expectedMonitoring.Ints["sampling.events.dropped"] = 0 - expectedMonitoring.Ints["sampling.events.failed_writes"] = 0 - assertMonitoring(t, processor, expectedMonitoring, `sampling.events.*`) + monitoringtest.ExpectContainOtelMetrics(t, tempdirConfig.metricReader, map[string]any{ + "apm-server.sampling.tail.events.processed": 4, + "apm-server.sampling.tail.events.stored": 2, + "apm-server.sampling.tail.events.sampled": 2, + }) // Stop the processor and flush global storage so we can access the database. assert.NoError(t, processor.Stop(context.Background())) - assert.NoError(t, config.Storage.Flush()) - reader := storage.NewReadWriter() - defer reader.Close() + assert.NoError(t, config.DB.Flush()) + reader := config.DB.NewReadWriter() batch = nil err = reader.ReadTraceEvents(trace1.Id, &batch) @@ -168,7 +152,8 @@ func TestProcessLocalTailSampling(t *testing.T) { }, } { t.Run(fmt.Sprintf("%f", tc.sampleRate), func(t *testing.T) { - config := newTempdirConfig(t) + tempdirConfig := newTempdirConfig(t) + config := tempdirConfig.Config config.Policies = []sampling.Policy{{SampleRate: tc.sampleRate}} config.FlushInterval = 10 * time.Millisecond published := make(chan string) @@ -249,21 +234,16 @@ func TestProcessLocalTailSampling(t *testing.T) { sampledTraceEvents = trace2Events } - expectedMonitoring := monitoring.MakeFlatSnapshot() - expectedMonitoring.Ints["sampling.events.processed"] = 4 - expectedMonitoring.Ints["sampling.events.stored"] = 4 - expectedMonitoring.Ints["sampling.events.sampled"] = 2 - expectedMonitoring.Ints["sampling.events.head_unsampled"] = 0 - expectedMonitoring.Ints["sampling.events.dropped"] = 0 - expectedMonitoring.Ints["sampling.events.failed_writes"] = 0 - assertMonitoring(t, processor, expectedMonitoring, `sampling.events.*`) + monitoringtest.ExpectContainOtelMetrics(t, tempdirConfig.metricReader, map[string]any{ + "apm-server.sampling.tail.events.processed": 4, + "apm-server.sampling.tail.events.stored": 4, + "apm-server.sampling.tail.events.sampled": 2, + }) // Stop the processor and flush global storage so we can access the database. assert.NoError(t, processor.Stop(context.Background())) - assert.NoError(t, config.Storage.Flush()) - storage := eventstorage.New(config.DB, eventstorage.ProtobufCodec{}) - reader := storage.NewReadWriter() - defer reader.Close() + assert.NoError(t, config.DB.Flush()) + reader := config.DB.NewReadWriter() sampled, err := reader.IsTraceSampled(sampledTraceID) assert.NoError(t, err) @@ -291,7 +271,8 @@ func TestProcessLocalTailSampling(t *testing.T) { } func TestProcessLocalTailSamplingUnsampled(t *testing.T) { - config := newTempdirConfig(t) + tempdirConfig := newTempdirConfig(t) + config := tempdirConfig.Config config.FlushInterval = time.Minute processor, err := sampling.NewProcessor(config) require.NoError(t, err) @@ -317,7 +298,7 @@ func TestProcessLocalTailSamplingUnsampled(t *testing.T) { assert.Empty(t, batch) // break out of the loop as soon as the first one is dropped. - droppedEvents := collectProcessorMetrics(processor).Ints["sampling.events.dropped"] + droppedEvents := getSum(t, tempdirConfig.metricReader, "apm-server.sampling.events.dropped") if droppedEvents != 0 { break } @@ -325,10 +306,8 @@ func TestProcessLocalTailSamplingUnsampled(t *testing.T) { // Stop the processor so we can access the database. assert.NoError(t, processor.Stop(context.Background())) - assert.NoError(t, config.Storage.Flush()) - storage := eventstorage.New(config.DB, eventstorage.ProtobufCodec{}) - reader := storage.NewReadWriter() - defer reader.Close() + assert.NoError(t, config.DB.Flush()) + reader := config.DB.NewReadWriter() var anyUnsampled bool for _, traceID := range traceIDs { @@ -347,7 +326,7 @@ func TestProcessLocalTailSamplingUnsampled(t *testing.T) { } func TestProcessLocalTailSamplingPolicyOrder(t *testing.T) { - config := newTempdirConfig(t) + config := newTempdirConfig(t).Config config.Policies = []sampling.Policy{{ PolicyCriteria: sampling.PolicyCriteria{TraceName: "trace_name"}, SampleRate: 0.5, @@ -414,7 +393,8 @@ func TestProcessLocalTailSamplingPolicyOrder(t *testing.T) { } func TestProcessRemoteTailSampling(t *testing.T) { - config := newTempdirConfig(t) + tempdirConfig := newTempdirConfig(t) + config := tempdirConfig.Config config.Policies = []sampling.Policy{{SampleRate: 0.5}} config.FlushInterval = 10 * time.Millisecond @@ -479,23 +459,18 @@ func TestProcessRemoteTailSampling(t *testing.T) { // Stop the processor and flush global storage so we can access the database. assert.NoError(t, processor.Stop(context.Background())) - assert.NoError(t, config.Storage.Flush()) + assert.NoError(t, config.DB.Flush()) assert.Empty(t, published) // remote decisions don't get republished - expectedMonitoring := monitoring.MakeFlatSnapshot() - expectedMonitoring.Ints["sampling.events.processed"] = 1 - expectedMonitoring.Ints["sampling.events.stored"] = 1 - expectedMonitoring.Ints["sampling.events.sampled"] = 1 - expectedMonitoring.Ints["sampling.events.head_unsampled"] = 0 - expectedMonitoring.Ints["sampling.events.dropped"] = 0 - expectedMonitoring.Ints["sampling.events.failed_writes"] = 0 - assertMonitoring(t, processor, expectedMonitoring, `sampling.events.*`) + monitoringtest.ExpectContainOtelMetrics(t, tempdirConfig.metricReader, map[string]any{ + "apm-server.sampling.tail.events.processed": 1, + "apm-server.sampling.tail.events.stored": 1, + "apm-server.sampling.tail.events.sampled": 1, + }) assert.Empty(t, cmp.Diff(trace1Events, events, protocmp.Transform())) - storage := eventstorage.New(config.DB, eventstorage.ProtobufCodec{}) - reader := storage.NewReadWriter() - defer reader.Close() + reader := config.DB.NewReadWriter() sampled, err := reader.IsTraceSampled(traceID1) assert.NoError(t, err) @@ -516,8 +491,72 @@ func TestProcessRemoteTailSampling(t *testing.T) { assert.Empty(t, batch) } +type errorRW struct { + err error +} + +func (m errorRW) ReadTraceEvents(traceID string, out *modelpb.Batch) error { + return m.err +} + +func (m errorRW) WriteTraceEvent(traceID, id string, event *modelpb.APMEvent) error { + return m.err +} + +func (m errorRW) WriteTraceSampled(traceID string, sampled bool) error { + return m.err +} + +func (m errorRW) IsTraceSampled(traceID string) (bool, error) { + return false, eventstorage.ErrNotFound +} + +func (m errorRW) DeleteTraceEvent(traceID, id string) error { + return m.err +} + +func (m errorRW) Flush() error { + return m.err +} + +func TestProcessDiscardOnWriteFailure(t *testing.T) { + for _, discard := range []bool{true, false} { + t.Run(fmt.Sprintf("discard=%v", discard), func(t *testing.T) { + config := newTempdirConfig(t).Config + config.DiscardOnWriteFailure = discard + config.Storage = errorRW{err: errors.New("boom")} + processor, err := sampling.NewProcessor(config) + require.NoError(t, err) + go processor.Run() + defer processor.Stop(context.Background()) + + in := modelpb.Batch{{ + Trace: &modelpb.Trace{ + Id: "0102030405060708090a0b0c0d0e0f10", + }, + Span: &modelpb.Span{ + Type: "type", + Id: "0102030405060708", + }, + }} + out := in[:] + err = processor.ProcessBatch(context.Background(), &out) + require.NoError(t, err) + + if discard { + // Discarding by default + assert.Empty(t, out) + } else { + // Indexing by default + assert.Equal(t, in, out) + } + }) + } +} + func TestGroupsMonitoring(t *testing.T) { - config := newTempdirConfig(t) + tempdirConfig := newTempdirConfig(t) + config := tempdirConfig.Config config.MaxDynamicServices = 5 config.FlushInterval = time.Minute config.Policies[0].SampleRate = 0.99 @@ -541,24 +580,39 @@ func TestGroupsMonitoring(t *testing.T) { require.NoError(t, err) } - expectedMonitoring := monitoring.MakeFlatSnapshot() - expectedMonitoring.Ints["sampling.dynamic_service_groups"] = int64(config.MaxDynamicServices) - expectedMonitoring.Ints["sampling.events.processed"] = int64(config.MaxDynamicServices) + 2 - expectedMonitoring.Ints["sampling.events.stored"] = int64(config.MaxDynamicServices) - expectedMonitoring.Ints["sampling.events.dropped"] = 1 // final event dropped, after service limit reached - expectedMonitoring.Ints["sampling.events.sampled"] = 0 - expectedMonitoring.Ints["sampling.events.head_unsampled"] = 1 - expectedMonitoring.Ints["sampling.events.failed_writes"] = 0 - assertMonitoring(t, processor, expectedMonitoring, `sampling.events.*`, `sampling.dynamic_service_groups`) + monitoringtest.ExpectContainOtelMetrics(t, tempdirConfig.metricReader, map[string]any{ + "apm-server.sampling.tail.dynamic_service_groups": config.MaxDynamicServices, + "apm-server.sampling.tail.events.processed": config.MaxDynamicServices + 2, + "apm-server.sampling.tail.events.stored": config.MaxDynamicServices, + "apm-server.sampling.tail.events.dropped": 1, // final event dropped, after service limit reached + "apm-server.sampling.tail.events.head_unsampled": 1, + }) +} + +func getGauge(t testing.TB, reader sdkmetric.Reader, name string) int64 { + var rm metricdata.ResourceMetrics + assert.NoError(t, reader.Collect(context.Background(), &rm)) + + assert.NotEqual(t, 0, len(rm.ScopeMetrics)) + + for _, sm := range rm.ScopeMetrics { + for _, m := range sm.Metrics { + if m.Name == name { + return m.Data.(metricdata.Gauge[int64]).DataPoints[0].Value + } + } + } + + return 0 } func TestStorageMonitoring(t *testing.T) { - config := newTempdirConfig(t) + tempdirConfig := newTempdirConfig(t) + config := tempdirConfig.Config processor, err := sampling.NewProcessor(config) require.NoError(t, err) go processor.Run() - defer processor.Stop(context.Background()) for i := 0; i < 100; i++ { traceID := uuid.Must(uuid.NewV4()).String() batch := modelpb.Batch{{ @@ -575,97 +629,16 @@ func TestStorageMonitoring(t *testing.T) { assert.Empty(t, batch) } - // Stop the processor and create a new one, which will reopen storage - // and calculate the storage size. Otherwise we must wait for a minute - // (hard-coded in badger) for storage metrics to be updated. - processor.Stop(context.Background()) - processor, err = sampling.NewProcessor(config) + // Stop the processor, flushing pending writes. + err = processor.Stop(context.Background()) require.NoError(t, err) - metrics := collectProcessorMetrics(processor) - assert.NotZero(t, metrics.Ints, "sampling.storage.lsm_size") - assert.NotZero(t, metrics.Ints, "sampling.storage.value_log_size") -} - -func TestStorageGC(t *testing.T) { - if testing.Short() { - t.Skip("skipping slow test") - } - - config := newTempdirConfig(t) - config.TTL = 10 * time.Millisecond - config.FlushInterval = 10 * time.Millisecond + require.NoError(t, config.DB.Flush()) - // Create a new badger DB with smaller value log files so we can test GC. - config.DB.Close() - badgerDB, err := eventstorage.OpenBadger(config.StorageDir, 1024*1024) - require.NoError(t, err) - t.Cleanup(func() { badgerDB.Close() }) - config.DB = badgerDB - config.Storage = eventstorage. - New(config.DB, eventstorage.ProtobufCodec{}). - NewShardedReadWriter() - t.Cleanup(func() { config.Storage.Close() }) - - writeBatch := func(n int) { - config.StorageGCInterval = time.Minute // effectively disable - processor, err := sampling.NewProcessor(config) - require.NoError(t, err) - go processor.Run() - defer processor.Stop(context.Background()) - for i := 0; i < n; i++ { - traceID := uuid.Must(uuid.NewV4()).String() - batch := modelpb.Batch{{ - Trace: &modelpb.Trace{Id: traceID}, - Event: &modelpb.Event{Duration: uint64(123 * time.Millisecond)}, - Span: &modelpb.Span{ - Type: "type", - Id: traceID, - }, - }} - err := processor.ProcessBatch(context.Background(), &batch) - require.NoError(t, err) - assert.Empty(t, batch) - } - } - - vlogFilenames := func() []string { - entries, _ := os.ReadDir(config.StorageDir) - - var vlogs []string - for _, entry := range entries { - name := entry.Name() - if strings.HasSuffix(name, ".vlog") { - vlogs = append(vlogs, name) - } - } - sort.Strings(vlogs) - return vlogs - } - - // Process spans until value log files have been created. - // Garbage collection is disabled at this time. - for len(vlogFilenames()) < 3 { - writeBatch(500) - } - - config.StorageGCInterval = 10 * time.Millisecond - processor, err := sampling.NewProcessor(config) - require.NoError(t, err) - go processor.Run() - defer processor.Stop(context.Background()) - - // Wait for the first value log file to be garbage collected. - deadline := time.Now().Add(10 * time.Second) - for time.Now().Before(deadline) { - vlogs := vlogFilenames() - if len(vlogs) == 0 || vlogs[0] != "000000.vlog" { - // garbage collected - return - } - time.Sleep(10 * time.Millisecond) - } - t.Fatal("timed out waiting for value log garbage collection") + lsmSize := getGauge(t, tempdirConfig.metricReader, "apm-server.sampling.tail.storage.lsm_size") + assert.NotZero(t, lsmSize) + vlogSize := getGauge(t, tempdirConfig.metricReader, "apm-server.sampling.tail.storage.value_log_size") + assert.Zero(t, vlogSize) } func TestStorageLimit(t *testing.T) { @@ -674,10 +647,6 @@ func TestStorageLimit(t *testing.T) { // To update the database size during our test without waiting a full // minute, we store some span events, close and re-open the database, so // the size is updated. - if testing.Short() { - t.Skip("skipping slow test") - } - writeBatch := func(n int, c sampling.Config, assertBatch func(b modelpb.Batch)) *sampling.Processor { processor, err := sampling.NewProcessor(c) require.NoError(t, err) @@ -701,52 +670,43 @@ func TestStorageLimit(t *testing.T) { return processor } - config := newTempdirConfig(t) + tempdirConfig := newTempdirConfig(t) + config := tempdirConfig.Config + config.TTL = time.Hour // Write 5K span events and close the DB to persist to disk the storage // size and assert that none are reported immediately. writeBatch(5000, config, func(b modelpb.Batch) { assert.Empty(t, b, fmt.Sprintf("expected empty but size is %d", len(b))) }) - assert.NoError(t, config.Storage.Flush()) - config.Storage.Close() - assert.NoError(t, config.DB.Close()) - // Open a new instance of the badgerDB and check the size. - var err error - config.DB, err = eventstorage.OpenBadger(config.StorageDir, 1024*1024) - require.NoError(t, err) - t.Cleanup(func() { config.DB.Close() }) + err := config.DB.Reload() + assert.NoError(t, err) + + config.Storage = config.DB.NewReadWriter() lsm, vlog := config.DB.Size() - assert.GreaterOrEqual(t, lsm+vlog, int64(1024)) - - config.StorageLimit = 1024 // Set the storage limit to 1024 bytes. - // Create a massive 150K span batch (per CPU) to trigger the badger error - // Transaction too big, causing the ProcessBatch to report the some traces - // immediately. - // Rather than setting a static threshold, use the runtime.NumCPU as a - // multiplier since the sharded writers use that variable and the more CPUs - // we have, the more sharded writes we'll have, resulting in a greater buffer. - // To avoid huge test time on large systems do this incrementally - for i := 1; i < runtime.NumCPU(); i++ { - processor := writeBatch(150_000*i, config, func(b modelpb.Batch) { - assert.NotEmpty(t, b) - }) + assert.Greater(t, lsm+vlog, int64(10<<10)) - failedWrites := collectProcessorMetrics(processor).Ints["sampling.events.failed_writes"] - t.Log(failedWrites) - // Ensure that there are some failed writes. + config.StorageLimit = 10 << 10 // Set the storage limit to smaller than existing storage - if failedWrites >= 1 { - return - } + writeBatch(1000, config, func(b modelpb.Batch) { + assert.Len(t, b, 1000) + }) + + // Ensure that there are some failed writes. + failedWrites := getSum(t, tempdirConfig.metricReader, "apm-server.sampling.tail.events.failed_writes") + t.Log(failedWrites) + + if failedWrites >= 1 { + return } - t.Fatal("badger error never thrown") + t.Fatal("storage limit error never thrown") } func TestProcessRemoteTailSamplingPersistence(t *testing.T) { - config := newTempdirConfig(t) + tempdirConfig := newTempdirConfig(t) + config := tempdirConfig.Config config.Policies = []sampling.Policy{{SampleRate: 0.5}} config.FlushInterval = 10 * time.Millisecond @@ -760,7 +720,7 @@ func TestProcessRemoteTailSamplingPersistence(t *testing.T) { defer processor.Stop(context.Background()) // Wait for subscriber_position.json to be written to the storage directory. - subscriberPositionFile := filepath.Join(config.StorageDir, "subscriber_position.json") + subscriberPositionFile := filepath.Join(tempdirConfig.tempDir, "subscriber_position.json") data, info := waitFileModified(t, subscriberPositionFile, time.Time{}) assert.Equal(t, "{}", string(data)) @@ -770,7 +730,7 @@ func TestProcessRemoteTailSamplingPersistence(t *testing.T) { } func TestGracefulShutdown(t *testing.T) { - config := newTempdirConfig(t) + config := newTempdirConfig(t).Config sampleRate := 0.5 config.Policies = []sampling.Policy{{SampleRate: sampleRate}} config.FlushInterval = time.Minute // disable finalize @@ -797,9 +757,8 @@ func TestGracefulShutdown(t *testing.T) { assert.NoError(t, processor.ProcessBatch(context.Background(), &batch)) assert.Empty(t, batch) assert.NoError(t, processor.Stop(context.Background())) - assert.NoError(t, config.Storage.Flush()) - reader := eventstorage.New(config.DB, eventstorage.ProtobufCodec{}).NewReadWriter() + reader := config.DB.NewReadWriter() var count int for i := 0; i < totalTraces; i++ { @@ -810,103 +769,76 @@ func TestGracefulShutdown(t *testing.T) { assert.Equal(t, int(sampleRate*float64(totalTraces)), count) } -func newTempdirConfig(tb testing.TB) sampling.Config { +type testConfig struct { + sampling.Config + tempDir string + metricReader sdkmetric.Reader +} + +func newTempdirConfig(tb testing.TB) testConfig { tempdir, err := os.MkdirTemp("", "samplingtest") require.NoError(tb, err) tb.Cleanup(func() { os.RemoveAll(tempdir) }) - badgerDB, err := eventstorage.OpenBadger(tempdir, 0) + reader := sdkmetric.NewManualReader(sdkmetric.WithTemporalitySelector( + func(ik sdkmetric.InstrumentKind) metricdata.Temporality { + return metricdata.DeltaTemporality + }, + )) + mp := sdkmetric.NewMeterProvider(sdkmetric.WithReader(reader)) + + db, err := eventstorage.NewStorageManager(tempdir, eventstorage.WithMeterProvider(mp)) require.NoError(tb, err) - tb.Cleanup(func() { badgerDB.Close() }) - - eventCodec := eventstorage.ProtobufCodec{} - storage := eventstorage.New(badgerDB, eventCodec).NewShardedReadWriter() - tb.Cleanup(func() { storage.Close() }) - - return sampling.Config{ - BatchProcessor: modelpb.ProcessBatchFunc(func(context.Context, *modelpb.Batch) error { return nil }), - LocalSamplingConfig: sampling.LocalSamplingConfig{ - FlushInterval: time.Second, - MaxDynamicServices: 1000, - IngestRateDecayFactor: 0.9, - Policies: []sampling.Policy{ - {SampleRate: 0.1}, + tb.Cleanup(func() { db.Close() }) + + return testConfig{ + tempDir: tempdir, + metricReader: reader, + Config: sampling.Config{ + BatchProcessor: modelpb.ProcessBatchFunc(func(context.Context, *modelpb.Batch) error { return nil }), + MeterProvider: mp, + LocalSamplingConfig: sampling.LocalSamplingConfig{ + FlushInterval: time.Second, + MaxDynamicServices: 1000, + IngestRateDecayFactor: 0.9, + Policies: []sampling.Policy{ + {SampleRate: 0.1}, + }, }, - }, - RemoteSamplingConfig: sampling.RemoteSamplingConfig{ - Elasticsearch: pubsubtest.Client(nil, nil), - SampledTracesDataStream: sampling.DataStreamConfig{ - Type: "traces", - Dataset: "sampled", - Namespace: "testing", + RemoteSamplingConfig: sampling.RemoteSamplingConfig{ + Elasticsearch: pubsubtest.Client(nil, nil), + SampledTracesDataStream: sampling.DataStreamConfig{ + Type: "traces", + Dataset: "sampled", + Namespace: "testing", + }, + UUID: "local-apm-server", + }, + StorageConfig: sampling.StorageConfig{ + DB: db, + Storage: db.NewReadWriter(), + TTL: 30 * time.Minute, + StorageLimit: 0, // No storage limit. }, - UUID: "local-apm-server", - }, - StorageConfig: sampling.StorageConfig{ - DB: badgerDB, - Storage: storage, - StorageDir: tempdir, - StorageGCInterval: time.Second, - TTL: 30 * time.Minute, - StorageLimit: 0, // No storage limit. }, } } -func assertMonitoring(t testing.TB, p *sampling.Processor, expected monitoring.FlatSnapshot, matches ...string) { - t.Helper() - actual := collectProcessorMetrics(p) - matchAny := func(k string) bool { return true } - if len(matches) > 0 { - matchAny = func(k string) bool { - for _, pattern := range matches { - matched, err := path.Match(pattern, k) - if err != nil { - panic(err) - } - if matched { - return true - } +func getSum(t testing.TB, reader sdkmetric.Reader, name string) int64 { + var rm metricdata.ResourceMetrics + assert.NoError(t, reader.Collect(context.Background(), &rm)) + + assert.NotEqual(t, 0, len(rm.ScopeMetrics)) + + for _, sm := range rm.ScopeMetrics { + for _, m := range sm.Metrics { + if m.Name == name { + return m.Data.(metricdata.Sum[int64]).DataPoints[0].Value } - return false - } - } - for k := range actual.Bools { - if !matchAny(k) { - delete(actual.Bools, k) - } - } - for k := range actual.Ints { - if !matchAny(k) { - delete(actual.Ints, k) } } - for k := range actual.Floats { - if !matchAny(k) { - delete(actual.Floats, k) - } - } - for k := range actual.Strings { - if !matchAny(k) { - delete(actual.Strings, k) - } - } - for k := range actual.StringSlices { - if !matchAny(k) { - delete(actual.StringSlices, k) - } - } - assert.Equal(t, expected, actual) -} -func collectProcessorMetrics(p *sampling.Processor) monitoring.FlatSnapshot { - registry := monitoring.NewRegistry() - monitoring.NewFunc(registry, "sampling", p.CollectMonitoring) - return monitoring.CollectFlatSnapshot( - registry, - monitoring.Full, - false, // expvar - ) + return 0 } // waitFileModified waits up to 10 seconds for filename to exist and for its diff --git a/x-pack/apm-server/sampling/pubsub/pubsub_integration_test.go b/x-pack/apm-server/sampling/pubsub/pubsub_integration_test.go index 7927a279776..f27eeecb458 100644 --- a/x-pack/apm-server/sampling/pubsub/pubsub_integration_test.go +++ b/x-pack/apm-server/sampling/pubsub/pubsub_integration_test.go @@ -14,7 +14,7 @@ import ( "testing" "time" - "github.com/gofrs/uuid" + "github.com/gofrs/uuid/v5" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "golang.org/x/sync/errgroup" diff --git a/x-pack/apm-server/sampling/pubsub/pubsub_test.go b/x-pack/apm-server/sampling/pubsub/pubsub_test.go index 5bb73f6b538..e7e52086d8d 100644 --- a/x-pack/apm-server/sampling/pubsub/pubsub_test.go +++ b/x-pack/apm-server/sampling/pubsub/pubsub_test.go @@ -17,7 +17,7 @@ import ( "testing" "time" - "github.com/gofrs/uuid" + "github.com/gofrs/uuid/v5" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "golang.org/x/sync/errgroup"