From c00ce00a8457cd6f1e53d4d2e20280fb93703443 Mon Sep 17 00:00:00 2001 From: v-byte-cpu <65545655+v-byte-cpu@users.noreply.github.com> Date: Sun, 9 Aug 2026 18:37:35 +0400 Subject: [PATCH] chore!: modernize toolchain and project automation Migrate CI and release automation from Drone to GitHub Actions. Upgrade Go and CoreDNS dependencies, modernize linting, adopt generated typed mocks, and verify full CoreDNS builds in CI. Rename the plugin directive to dohproxy to coexist with the built-in CoreDNS https plugin and document local integration testing. BREAKING CHANGE: Go 1.26.0 or later is now required. The Corefile directive is renamed from https to dohproxy, and Prometheus metric prefixes change from coredns_https_ to coredns_dohproxy_. --- .commitlintrc.yml | 5 + .drone.yml | 42 -- .github/workflows/ci.yml | 104 +++++ .github/workflows/commitlint.yml | 50 +++ .github/workflows/release.yml | 78 ++++ .golangci.yml | 68 +++- .revive.toml | 44 --- README.md | 89 +++-- cliff.toml | 40 ++ go.mod | 57 +-- go.sum | 632 +++++-------------------------- https.go | 2 +- https_test.go | 75 ++-- metrics.go | 6 +- mocks_dns_test.go | 343 +++++++++++++++++ mocks_internal_test.go | 145 +++++++ policy_test.go | 14 +- proxy.go | 3 + proxy_test.go | 126 +++--- setup.go | 9 +- setup_test.go | 60 +-- 21 files changed, 1171 insertions(+), 821 deletions(-) create mode 100644 .commitlintrc.yml delete mode 100644 .drone.yml create mode 100644 .github/workflows/ci.yml create mode 100644 .github/workflows/commitlint.yml create mode 100644 .github/workflows/release.yml delete mode 100644 .revive.toml create mode 100644 cliff.toml create mode 100644 mocks_dns_test.go create mode 100644 mocks_internal_test.go diff --git a/.commitlintrc.yml b/.commitlintrc.yml new file mode 100644 index 0000000..8bc6ddb --- /dev/null +++ b/.commitlintrc.yml @@ -0,0 +1,5 @@ +extends: + - '@commitlint/config-conventional' + +rules: + header-max-length: [0, 'always', 100] diff --git a/.drone.yml b/.drone.yml deleted file mode 100644 index 3e01a0c..0000000 --- a/.drone.yml +++ /dev/null @@ -1,42 +0,0 @@ ---- -kind: pipeline -type: docker -name: coredns-https-ci - -trigger: - ref: - - refs/heads/main - - refs/pull/*/head - - refs/tags/* - event: - - push - - tag - - pull_request - -clone: - depth: 1 - -steps: - - name: lint - image: golangci/golangci-lint:v1.48-alpine - volumes: - - name: deps - path: /go - commands: - - golangci-lint run -v - - go install github.com/mgechev/revive@v1.2.3 - - revive -config .revive.toml -formatter friendly ./... - - - name: test - image: golang:1.19-alpine - environment: - CGO_ENABLED: "0" - volumes: - - name: deps - path: /go - commands: - - go test ./... -v -cover - -volumes: - - name: deps - temp: {} \ No newline at end of file diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..c6767a5 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,104 @@ +name: CI + +on: + push: + branches: [main] + pull_request: + branches: [main] + +concurrency: + group: ci-${{ github.ref }} + cancel-in-progress: true + +permissions: + contents: read + +jobs: + changes: + runs-on: ubuntu-latest + outputs: + go_ci: ${{ steps.filter.outputs.go_ci }} + + steps: + - name: Checkout repository + uses: actions/checkout@v6 + + - name: Detect changed paths + id: filter + uses: dorny/paths-filter@v4 + with: + filters: | + go_ci: + - '**/*.go' + - 'go.mod' + - 'go.sum' + - '.golangci.yml' + - '.github/workflows/ci.yml' + + go: + needs: changes + if: needs.changes.outputs.go_ci == 'true' + runs-on: ubuntu-latest + container: golang:1.26-alpine + env: + CGO_ENABLED: 0 + GOFLAGS: -buildvcs=false + GOMODCACHE: /go/pkg/mod + GOCACHE: /root/.cache/go-build + defaults: + run: + shell: bash + + steps: + - name: Install system dependencies + shell: sh + run: apk add --no-cache bash ca-certificates git + + - name: Checkout repository + uses: actions/checkout@v6 + + - name: Cache Go modules and build outputs + uses: actions/cache@v5 + with: + path: | + /go/pkg/mod + /root/.cache/go-build + key: ${{ runner.os }}-go-1.26-${{ hashFiles('**/go.sum') }} + restore-keys: | + ${{ runner.os }}-go-1.26- + + - name: Verify generated files and module metadata + run: | + git config --global --add safe.directory "$GITHUB_WORKSPACE" + go generate ./... + go mod tidy + git diff --exit-code + + - name: Check Go formatting + run: test -z "$(gofmt -l .)" + + - name: Run golangci-lint + uses: golangci/golangci-lint-action@v9 + with: + version: v2.12 + args: --verbose + + - name: Run Go tests + run: go test ./... -v -cover + + - name: Run Go build + run: go build ./... + + - name: Build CoreDNS with the local plugin + run: | + plugin_dir="$GITHUB_WORKSPACE" + coredns_version="$(go list -m -f '{{.Version}}' github.com/coredns/coredns)" + coredns_dir="$(mktemp -d)" + + git clone --depth 1 --branch "$coredns_version" https://github.com/coredns/coredns.git "$coredns_dir" + cd "$coredns_dir" + go mod edit -replace "github.com/v-byte-cpu/coredns-https=$plugin_dir" + go get github.com/v-byte-cpu/coredns-https@v0.0.0 + COREDNS_PLUGINS="dohproxy:github.com/v-byte-cpu/coredns-https" go generate coredns.go + go build -o coredns . + ./coredns -plugins | grep -Fx dohproxy diff --git a/.github/workflows/commitlint.yml b/.github/workflows/commitlint.yml new file mode 100644 index 0000000..bc7b609 --- /dev/null +++ b/.github/workflows/commitlint.yml @@ -0,0 +1,50 @@ +name: Commit checks + +on: + push: + branches: [main] + pull_request: + branches: [main] + +concurrency: + group: commitlint-${{ github.ref }} + cancel-in-progress: true + +permissions: + contents: read + +jobs: + commitlint: + if: >- + (github.event_name == 'pull_request' && github.event.pull_request.user.login != 'dependabot[bot]') + || (github.event_name == 'push' && github.event.head_commit.author.name != 'dependabot[bot]') + runs-on: ubuntu-latest + + steps: + - name: Enforce single-commit PRs + if: github.event_name == 'pull_request' + env: + PR_COMMIT_COUNT: ${{ github.event.pull_request.commits }} + run: test "$PR_COMMIT_COUNT" -eq 1 + + - name: Checkout repository + uses: actions/checkout@v6 + with: + ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }} + + - name: Set up Node + uses: actions/setup-node@v6 + with: + node-version: "22" + + - name: Install commitlint + run: npm install --no-save --no-package-lock @commitlint/cli @commitlint/config-conventional + + - name: Validate PR title + if: github.event_name == 'pull_request' + env: + PR_TITLE: ${{ github.event.pull_request.title }} + run: printf '%s\n' "$PR_TITLE" | npx commitlint --verbose + + - name: Validate last commit + run: npx commitlint --last --verbose diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..86f98f8 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,78 @@ +name: release + +on: + push: + tags: + - 'v*' + +permissions: + contents: write + +concurrency: + group: release-${{ github.ref }} + cancel-in-progress: false + +jobs: + release: + runs-on: ubuntu-latest + env: + NOTES_PATH: ${{ github.workspace }}/release-notes.md + defaults: + run: + shell: bash + + steps: + - name: Validate release tag + id: release_flags + env: + RELEASE_TAG: ${{ github.ref_name }} + run: | + set -euo pipefail + + if [[ ! "${RELEASE_TAG}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+(-rc\.[0-9]+)?$ ]]; then + echo "invalid release tag: ${RELEASE_TAG}" >&2 + exit 1 + fi + + if [[ "${RELEASE_TAG}" =~ -rc\.[0-9]+$ ]]; then + echo "prerelease=true" >> "$GITHUB_OUTPUT" + echo "make_latest=false" >> "$GITHUB_OUTPUT" + else + echo "prerelease=false" >> "$GITHUB_OUTPUT" + echo "make_latest=true" >> "$GITHUB_OUTPUT" + fi + + - name: Checkout repository + uses: actions/checkout@v6 + with: + ref: ${{ github.ref }} + fetch-depth: 0 + fetch-tags: true + + - name: Install git-cliff + uses: taiki-e/install-action@git-cliff + + - name: Generate release notes + env: + RELEASE_TAG: ${{ github.ref_name }} + run: | + set -euo pipefail + + ignore_rc_tags='^v[0-9]+\.[0-9]+\.[0-9]+-rc\.[0-9]+$' + if [[ "${RELEASE_TAG}" =~ -rc\.[0-9]+$ ]]; then + git-cliff --current --output "${NOTES_PATH}" + else + git-cliff --current --ignore-tags "${ignore_rc_tags}" --output "${NOTES_PATH}" + fi + + cat "${NOTES_PATH}" >> "$GITHUB_STEP_SUMMARY" + + - name: Create draft GitHub Release + uses: softprops/action-gh-release@v3 + with: + tag_name: ${{ github.ref_name }} + name: ${{ github.ref_name }} + body_path: ${{ env.NOTES_PATH }} + draft: true + prerelease: ${{ steps.release_flags.outputs.prerelease }} + make_latest: ${{ steps.release_flags.outputs.make_latest }} diff --git a/.golangci.yml b/.golangci.yml index 8b82b67..ed4fe5d 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -1,31 +1,71 @@ +version: "2" + linters: + disable: + - errcheck enable: - dogsled - - errname - - errorlint - - exportloopref + - gochecknoinits - funlen - gocognit - goconst - gocritic - gocyclo - - gofmt - - goimports + - nolintlint + - paralleltest + - testifylint - staticcheck - gosec - - govet - misspell - nestif - prealloc + - revive - unconvert - unparam + exclusions: + rules: + # CoreDNS external plugins must register themselves during package initialization. + - linters: + - gochecknoinits + path: setup\.go + text: "don't use `init` function" + # Runtime configuration limits poolLen to maxUpstreams before this conversion. + - linters: + - gosec + path: policy\.go + text: "G115" + - linters: + - funlen + - goconst + path: _test\.go + settings: + revive: + severity: warning + confidence: 0.8 + rules: + - name: blank-imports + - name: context-as-argument + - name: context-keys-type + - name: dot-imports + - name: error-return + - name: error-strings + - name: empty-block + - name: superfluous-else + - name: unhandled-error + - name: unused-receiver + - name: unreachable-code + - name: range-val-in-closure + - name: range-val-address + - name: waitgroup-by-value + - name: atomic + - name: early-return + - name: unconditional-recursion + - name: identical-branches -run: - timeout: 5m +formatters: + enable: + - gofmt + - goimports -issues: - exclude-rules: - - linters: - - funlen - - gosec - path: _test\.go \ No newline at end of file +run: + timeout: 3m diff --git a/.revive.toml b/.revive.toml deleted file mode 100644 index 06b6bf0..0000000 --- a/.revive.toml +++ /dev/null @@ -1,44 +0,0 @@ -ignoreGeneratedHeader = false -severity = "warning" -confidence = 0.8 -errorCode = 1 -warningCode = 1 - -#Recommended rules -[rule.blank-imports] -[rule.context-as-argument] -[rule.context-keys-type] -[rule.dot-imports] -[rule.error-return] -[rule.error-strings] -[rule.error-naming] -[rule.if-return] -[rule.increment-decrement] -[rule.var-naming] -[rule.var-declaration] -[rule.package-comments] -[rule.range] -[rule.receiver-naming] -[rule.time-naming] -[rule.unexported-return] -[rule.indent-error-flow] -[rule.errorf] -[rule.empty-block] -[rule.superfluous-else] -[rule.unused-parameter] -[rule.unreachable-code] -[rule.redefines-builtin-id] - -#Custom rules -[rule.modifies-parameter] -[rule.unnecessary-stmt] -[rule.modifies-value-receiver] -[rule.range-val-in-closure] -[rule.range-val-address] -[rule.waitgroup-by-value] -[rule.atomic] -[rule.unused-receiver] -[rule.early-return] -[rule.unconditional-recursion] -[rule.identical-branches] -[rule.defer] \ No newline at end of file diff --git a/README.md b/README.md index 81a53ed..db4ee5f 100644 --- a/README.md +++ b/README.md @@ -1,27 +1,67 @@ -# https +# coredns-https -[![Build Status](https://cloud.drone.io/api/badges/v-byte-cpu/coredns-https/status.svg)](https://cloud.drone.io/v-byte-cpu/coredns-https) -[![GoReportCard Status](https://goreportcard.com/badge/github.com/v-byte-cpu/coredns-https)](https://goreportcard.com/report/github.com/v-byte-cpu/coredns-https) +[![CI](https://github.com/v-byte-cpu/coredns-https/actions/workflows/ci.yml/badge.svg)](https://github.com/v-byte-cpu/coredns-https/actions/workflows/ci.yml) [![GitHub release](https://img.shields.io/github/v/release/v-byte-cpu/coredns-https)](https://github.com/v-byte-cpu/coredns-https/releases/latest) -**https** is a [CoreDNS](https://github.com/coredns/coredns) plugin that proxies DNS messages to upstream resolvers using DNS-over-HTTPS protocol. See [RFC 8484](https://tools.ietf.org/html/rfc8484). +**coredns-https** provides the `dohproxy` [CoreDNS](https://github.com/coredns/coredns) +plugin, which proxies DNS messages to upstream resolvers using DNS-over-HTTPS. +See [RFC 8484](https://www.rfc-editor.org/rfc/rfc8484.html). ## Installation -External CoreDNS plugins can be enabled in one of two ways: - 1. [Build with compile-time configuration file](https://coredns.io/2017/07/25/compile-time-enabling-or-disabling-plugins/#build-with-compile-time-configuration-file) - 2. [Build with external golang source code](https://coredns.io/2017/07/25/compile-time-enabling-or-disabling-plugins/#build-with-external-golang-source-code) +The plugin must be compiled into CoreDNS. The following commands build the latest plugin release +against the tested CoreDNS version: -Method #1 can be quickly described using a sequence of the following commands: +```sh +git clone --depth 1 --branch v1.14.6 https://github.com/coredns/coredns.git +cd coredns +go get github.com/v-byte-cpu/coredns-https@latest +COREDNS_PLUGINS="dohproxy:github.com/v-byte-cpu/coredns-https" go generate coredns.go +go build +./coredns -plugins | grep -Fx dohproxy +``` + +> [!IMPORTANT] +> The Corefile directive was renamed from `https` to `dohproxy` to avoid a collision with the +> built-in CoreDNS `https` plugin. Prometheus metrics were also renamed from +> `coredns_https_*` to `coredns_dohproxy_*`. + +## Local development +Run the unit tests first: + +```sh +go test ./... ``` -git clone --depth 1 https://github.com/coredns/coredns.git + +To test the current checkout in a real CoreDNS binary, clone the tested CoreDNS version into a +separate directory and replace the module with the absolute path to this repository: + +```sh +git clone --depth 1 --branch v1.14.6 https://github.com/coredns/coredns.git cd coredns -go get github.com/v-byte-cpu/coredns-https -echo "https:github.com/v-byte-cpu/coredns-https" >> plugin.cfg -go generate -go mod tidy -compat=1.17 +go mod edit -replace github.com/v-byte-cpu/coredns-https=/absolute/path/to/coredns-https +go get github.com/v-byte-cpu/coredns-https@v0.0.0 +COREDNS_PLUGINS="dohproxy:github.com/v-byte-cpu/coredns-https" go generate coredns.go go build +./coredns -plugins | grep -Fx dohproxy +``` + +Create a `Corefile` for a manual end-to-end check: + +~~~ corefile +.:1053 { + dohproxy . cloudflare-dns.com/dns-query + errors + log +} +~~~ + +Start CoreDNS, then query it from another terminal: + +```sh +./coredns -conf Corefile +dig @127.0.0.1 -p 1053 example.org A ``` ## Syntax @@ -29,7 +69,7 @@ go build In its most basic form: ~~~ -https FROM TO... +dohproxy FROM TO... ~~~ * **FROM** is the base domain to match for the request to be proxied. @@ -42,7 +82,7 @@ the next upstream in the list is tried. Extra knobs are available with an expanded syntax: ~~~ -https FROM TO... { +dohproxy FROM TO... { except IGNORED_NAMES... tls CERT KEY CA tls_servername NAME @@ -68,12 +108,11 @@ https FROM TO... { ## Metrics -If monitoring is enabled (via the *prometheus* plugin) then the following metric are exported: +If monitoring is enabled via the *prometheus* plugin, the following metrics are exported: -* `coredns_https_request_duration_seconds{to}` - duration per upstream interaction. -* `coredns_https_requests_total{to}` - query count per upstream. -* `coredns_https_responses_total{to, rcode}` - count of RCODEs per upstream. - and we are randomly (this always uses the `random` policy) spraying to an upstream. +* `coredns_dohproxy_request_duration_seconds{to}` - duration per upstream interaction. +* `coredns_dohproxy_requests_total{to}` - query count per upstream. +* `coredns_dohproxy_responses_total{to, rcode}` - count of RCODEs per upstream. ## Examples @@ -81,7 +120,7 @@ Proxy all requests within `example.org.` to a DoH nameserver: ~~~ corefile example.org { - https . cloudflare-dns.com/dns-query + dohproxy . cloudflare-dns.com/dns-query } ~~~ @@ -89,7 +128,7 @@ Forward everything except requests to `example.org` ~~~ corefile . { - https . dns.quad9.net/dns-query { + dohproxy . dns.quad9.net/dns-query { except example.org } } @@ -99,7 +138,7 @@ Load balance all requests between multiple upstreams ~~~ corefile . { - https . dns.quad9.net/dns-query cloudflare-dns.com:443/dns-query dns.google/dns-query + dohproxy . dns.quad9.net/dns-query cloudflare-dns.com:443/dns-query dns.google/dns-query } ~~~ @@ -107,9 +146,9 @@ Internal DoH server: ~~~ corefile . { - https . 10.0.0.10:853/dns-query { + dohproxy . 10.0.0.10:853/dns-query { tls ca.crt tls_servername internal.domain } } -~~~ \ No newline at end of file +~~~ diff --git a/cliff.toml b/cliff.toml new file mode 100644 index 0000000..ebe7903 --- /dev/null +++ b/cliff.toml @@ -0,0 +1,40 @@ +# https://git-cliff.org/docs/configuration + +[changelog] + +body = """ +{% for group, commits in commits | group_by(attribute="group") %} +## {{ group | striptags | trim }} + +{% for commit in commits -%} +- {% if commit.scope %}*({{ commit.scope }})* {% endif %}{% if commit.breaking %}[**breaking**] {% endif %}{{ commit.message | upper_first }} +{% endfor -%} + +{% endfor %} +""" + +trim = true + +[bump] +initial_tag = "v0.1.0" +breaking_always_bump_major = false + +[git] +conventional_commits = true +tag_pattern = "^v[0-9]+\\.[0-9]+\\.[0-9]+(?:-rc\\.[0-9]+)?$" + +commit_parsers = [ + { message = "^feat", group = "New Features" }, + { message = "^fix", group = "Bug Fixes" }, + { message = "^docs", group = "Documentation" }, + { message = "^refactor", group = "Refactoring" }, + { message = "^perf", group = "Performance" }, + { message = "^ci", group = "CI" }, + { message = "^test", group = "Tests" }, + { message = "^(build|chore)", group = "Chores" }, + { message = ".*", group = "Other" }, +] + +filter_unconventional = true +sort_commits = "oldest" +topo_order = false diff --git a/go.mod b/go.mod index 719e29a..7058023 100644 --- a/go.mod +++ b/go.mod @@ -1,37 +1,46 @@ module github.com/v-byte-cpu/coredns-https -go 1.19 +go 1.26.0 require ( - github.com/coredns/caddy v1.1.1 - github.com/coredns/coredns v1.9.3 - github.com/miekg/dns v1.1.50 - github.com/prometheus/client_golang v1.13.0 - github.com/stretchr/testify v1.8.0 + github.com/coredns/caddy v1.1.4 + github.com/coredns/coredns v1.14.6 + github.com/miekg/dns v1.1.72 + github.com/prometheus/client_golang v1.24.1 + github.com/stretchr/testify v1.11.1 + go.uber.org/mock v0.6.0 ) require ( - github.com/apparentlymart/go-cidr v1.1.0 // indirect + github.com/apparentlymart/go-cidr v1.1.1 // indirect github.com/beorn7/perks v1.0.1 // indirect - github.com/cespare/xxhash/v2 v2.1.2 // indirect - github.com/davecgh/go-spew v1.1.1 // indirect + github.com/cespare/xxhash/v2 v2.3.0 // indirect + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 // indirect - github.com/golang/protobuf v1.5.2 // indirect github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645 // indirect - github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect + github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect + github.com/kr/text v0.2.0 // indirect + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/opentracing/opentracing-go v1.2.0 // indirect - github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/prometheus/client_model v0.2.0 // indirect - github.com/prometheus/common v0.37.0 // indirect - github.com/prometheus/procfs v0.8.0 // indirect - golang.org/x/mod v0.4.2 // indirect - golang.org/x/net v0.0.0-20220520000938-2e3eb7b945c2 // indirect - golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a // indirect - golang.org/x/text v0.3.7 // indirect - golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2 // indirect - golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df // indirect - google.golang.org/genproto v0.0.0-20220519153652-3a47de7e79bd // indirect - google.golang.org/grpc v1.46.2 // indirect - google.golang.org/protobuf v1.28.1 // indirect + github.com/pires/go-proxyproto v0.13.0 // indirect + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect + github.com/prometheus/client_model v0.6.2 // indirect + github.com/prometheus/common v0.70.1 // indirect + github.com/prometheus/procfs v0.21.1 // indirect + github.com/quic-go/qpack v0.6.0 // indirect + github.com/quic-go/quic-go v0.60.0 // indirect + github.com/rogpeppe/go-internal v1.14.1 // indirect + golang.org/x/crypto v0.54.0 // indirect + golang.org/x/mod v0.37.0 // indirect + golang.org/x/net v0.57.0 // indirect + golang.org/x/sync v0.22.0 // indirect + golang.org/x/sys v0.47.0 // indirect + golang.org/x/text v0.40.0 // indirect + golang.org/x/tools v0.47.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260511170946-3700d4141b60 // indirect + google.golang.org/grpc v1.82.0 // indirect + google.golang.org/protobuf v1.36.11 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) + +tool go.uber.org/mock/mockgen diff --git a/go.sum b/go.sum index f436956..0ebc14a 100644 --- a/go.sum +++ b/go.sum @@ -1,551 +1,113 @@ -cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= -cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= -cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= -cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= -cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= -cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= -cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= -cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= -cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= -cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= -cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= -cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= -cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= -cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= -cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= -cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= -cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= -cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= -cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= -cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= -cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= -cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= -cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= -cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= -cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= -cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= -cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= -cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= -cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= -cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= -dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= -github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= -github.com/apparentlymart/go-cidr v1.1.0 h1:2mAhrMoF+nhXqxTzSZMUzDHkLjmIHC+Zzn4tdgBZjnU= -github.com/apparentlymart/go-cidr v1.1.0/go.mod h1:EBcsNrHc3zQeuaeCeCtQruQm+n9/YjEn/vI25Lg7Gwc= -github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= -github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/apparentlymart/go-cidr v1.1.1 h1:oEEk8CE0HP0YpHxsegk/TaOtR2FLHdWv4p3eM4ceUwg= +github.com/apparentlymart/go-cidr v1.1.1/go.mod h1:EBcsNrHc3zQeuaeCeCtQruQm+n9/YjEn/vI25Lg7Gwc= 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/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= -github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= -github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= -github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= -github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= -github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/coredns/caddy v1.1.1 h1:2eYKZT7i6yxIfGP3qLJoJ7HAsDJqYB+X68g4NYjSrE0= -github.com/coredns/caddy v1.1.1/go.mod h1:A6ntJQlAWuQfFlsd9hvigKbo2WS0VUs2l1e2F+BawD4= -github.com/coredns/coredns v1.9.3 h1:eYvVtY9n6qZhHGtQaiOu6ku87Mz9kkSP/6RvFZ48VtA= -github.com/coredns/coredns v1.9.3/go.mod h1:AS3cwa8gzBsPEqNI6p6LAVNaF7/0SgjjlQQ9JSrzncQ= +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/coredns/caddy v1.1.4 h1:+Lls5xASB0QsA2jpCroCOwpPlb5GjIGlxdjXxdX0XVo= +github.com/coredns/caddy v1.1.4/go.mod h1:A6ntJQlAWuQfFlsd9hvigKbo2WS0VUs2l1e2F+BawD4= +github.com/coredns/coredns v1.14.6 h1:V2g2JdCWJVqYGdX8tlBiK0iQo23Pnt8xs8gHqKyFYs8= +github.com/coredns/coredns v1.14.6/go.mod h1:uYFaWgxTC89XCtUZ1Siu184N3+MpaDVi9GvqHDBRbCY= +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 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= -github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= -github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= -github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +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/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 h1:BHsljHzVlRcyQhjrss6TZTdY2VfCqZPbv5k3iBFa2ZQ= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= -github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= -github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= -github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= -github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= -github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= -github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= -github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= -github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= -github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= -github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= -github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= -github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= -github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= -github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= -github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= -github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= -github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= -github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= +github.com/go-logr/logr v1.4.3/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/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.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= -github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +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-opentracing v0.0.0-20180507213350-8e809c8a8645 h1:MJG/KsmcqMwFAkh8mTnAwhyKoB+sTAnY4CACC110tbU= github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645/go.mod h1:6iZfnjpejD4L/4DwD7NryNaJyCQdzwWwH2MWhCA90Kw= -github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= -github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= -github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= -github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= -github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= -github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= -github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= -github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= -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/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= -github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/miekg/dns v1.1.50 h1:DQUfb9uc6smULcREF09Uc+/Gd46YWqJd5DbpPE9xkcA= -github.com/miekg/dns v1.1.50/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME= -github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= +github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= +github.com/miekg/dns v1.1.72 h1:vhmr+TF2A3tuoGNkLDFK9zi36F2LS+hKTRW0Uf8kbzI= +github.com/miekg/dns v1.1.72/go.mod h1:+EuEPhdHOsfk6Wk5TT2CzssZdqkmFhf8r+aVyDEToIs= +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/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/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/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pires/go-proxyproto v0.13.0 h1:kMrnyu6w92odDfOVzjYV6s5GqYGnIEKoxxsP38VrPSs= +github.com/pires/go-proxyproto v0.13.0/go.mod h1:qUvfqUMEoX7T8g0q7TQLDnhMjdTrxnG0hvpMn+7ePNI= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= -github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= -github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= -github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= -github.com/prometheus/client_golang v1.13.0 h1:b71QUfeo5M8gq2+evJdTPfZhYMAU0uKPkyPJ7TPsloU= -github.com/prometheus/client_golang v1.13.0/go.mod h1:vTeo+zgvILHsnnj/39Ou/1fPN5nJFOEMgftOUOmlvYQ= -github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M= -github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= -github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= -github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= -github.com/prometheus/common v0.37.0 h1:ccBbHCgIiT9uSoFY0vX8H3zsNR5eLt17/RQLUvn8pXE= -github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= -github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= -github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo= -github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4= -github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= -github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= +github.com/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/prometheus/client_golang v1.24.1 h1:JnJkREXzWxUdCuPFpIWZiPispT9xVV59uiuyR2bPlnU= +github.com/prometheus/client_golang v1.24.1/go.mod h1:F+oSRECHg4sse5ucfYpYDeIv/hu68Zo0uoHKetWnzcE= +github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk= +github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= +github.com/prometheus/common v0.70.1 h1:1HvjP4D5oL3t8RsPlwxA9onvvStjtIHYE5XuuwOi/PY= +github.com/prometheus/common v0.70.1/go.mod h1:VdFUQDMZK3VLkurFUVhia6uys/0suUp86TJz5qbJRhc= +github.com/prometheus/procfs v0.21.1 h1:GljZCt+zSTS+NZq88cyQ1LjZ+RCHp3uVuabBWA5+OJI= +github.com/prometheus/procfs v0.21.1/go.mod h1:aB55Cww9pdSJVHk0hUf0inxWyyjPogFIjmHKYgMKmtY= +github.com/quic-go/go-ossfuzz-seeds v0.1.0 h1:APacT+iIaNF6fd8AGEiN3bT/Jtkd2jz4v4TzM7MFjy0= +github.com/quic-go/go-ossfuzz-seeds v0.1.0/go.mod h1:3IOHRbJIc+L6YKMwfDtJAM9Vj9k0YY4muhuyUYk5tbk= +github.com/quic-go/qpack v0.6.0 h1:g7W+BMYynC1LbYLSqRt8PBg5Tgwxn214ZZR34VIOjz8= +github.com/quic-go/qpack v0.6.0/go.mod h1:lUpLKChi8njB4ty2bFLX2x4gzDqXwUpaO1DP9qMDZII= +github.com/quic-go/quic-go v0.60.0 h1:xcQioE8OM66UQLeUMHltK1CCcOu3JbVB4JAQdDQSB+0= +github.com/quic-go/quic-go v0.60.0/go.mod h1:wpKpjmPpftl30sL6pFh7REVpjbcCVy4zt2vDyK1TuJk= +github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= +github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= 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/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.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -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 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= -go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= -go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= -golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= -golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= -golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= -golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= -golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= -golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= -golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= -golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= -golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= -golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= -golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= -golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= -golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo= -golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220520000938-2e3eb7b945c2 h1:NWy5+hlRbC7HK+PmcXVUmW1IMyFce7to56IUvhUFm7Y= -golang.org/x/net v0.0.0-20220520000938-2e3eb7b945c2/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f h1:Ax0t5p6N38Ga0dThY21weqDEyz2oklo4IvDkpigvkD8= -golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-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-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a h1:dGzPydgVsqGcTRVwiLJ1jVbufYwmzD3LfVPLKsKg+0k= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -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/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.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 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= -golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= -golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2 h1:BonxutuHCTL0rBDnZlKjpGIQFTjyUVTexFOdWkB6Fg0= -golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df h1:5Pf6pFKu98ODmgnpvkJ3kFUOQGGLIzLIkbzUHp47618= -golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= -google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= -google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= -google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= -google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= -google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= -google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= -google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= -google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= -google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= -google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20220519153652-3a47de7e79bd h1:e0TwkXOdbnH/1x5rc5MZ/VYyiZ4v+RdVfrGMqEwT68I= -google.golang.org/genproto v0.0.0-20220519153652-3a47de7e79bd/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= -google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= -google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= -google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= -google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= -google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= -google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= -google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= -google.golang.org/grpc v1.46.2 h1:u+MLGgVf7vRdjEYZ8wDFhAVNmhkbJ5hmrA1LMWK1CAQ= -google.golang.org/grpc v1.46.2/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= -google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= -google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= -google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= -google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= -google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= -google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= -google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= +go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= +go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= +go.opentelemetry.io/otel v1.43.0 h1:mYIM03dnh5zfN7HautFE4ieIig9amkNANT+xcVxAj9I= +go.opentelemetry.io/otel v1.43.0/go.mod h1:JuG+u74mvjvcm8vj8pI5XiHy1zDeoCS2LB1spIq7Ay0= +go.opentelemetry.io/otel/metric v1.43.0 h1:d7638QeInOnuwOONPp4JAOGfbCEpYb+K6DVWvdxGzgM= +go.opentelemetry.io/otel/metric v1.43.0/go.mod h1:RDnPtIxvqlgO8GRW18W6Z/4P462ldprJtfxHxyKd2PY= +go.opentelemetry.io/otel/sdk v1.43.0 h1:pi5mE86i5rTeLXqoF/hhiBtUNcrAGHLKQdhg4h4V9Dg= +go.opentelemetry.io/otel/sdk v1.43.0/go.mod h1:P+IkVU3iWukmiit/Yf9AWvpyRDlUeBaRg6Y+C58QHzg= +go.opentelemetry.io/otel/sdk/metric v1.43.0 h1:S88dyqXjJkuBNLeMcVPRFXpRw2fuwdvfCGLEo89fDkw= +go.opentelemetry.io/otel/sdk/metric v1.43.0/go.mod h1:C/RJtwSEJ5hzTiUz5pXF1kILHStzb9zFlIEe85bhj6A= +go.opentelemetry.io/otel/trace v1.43.0 h1:BkNrHpup+4k4w+ZZ86CZoHHEkohws8AY+WTX09nk+3A= +go.opentelemetry.io/otel/trace v1.43.0/go.mod h1:/QJhyVBUUswCphDVxq+8mld+AvhXZLhe+8WVFxiFff0= +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/mock v0.6.0 h1:hyF9dfmbgIX5EfOdasqLsWD6xqpNZlXblLB/Dbnwv3Y= +go.uber.org/mock v0.6.0/go.mod h1:KiVJ4BqZJaMj4svdfmHM0AUx4NJYO8ZNpPnZn1Z+BBU= +go.yaml.in/yaml/v2 v2.4.4 h1:tuyd0P+2Ont/d6e2rl3be67goVK4R6deVxCUX5vyPaQ= +go.yaml.in/yaml/v2 v2.4.4/go.mod h1:gMZqIpDtDqOfM0uNfy0SkpRhvUryYH0Z6wdMYcacYXQ= +golang.org/x/crypto v0.54.0 h1:YLIA59K4fiNzHzjnZt2tUJQjQtUWfWbeHBqKtk3eScw= +golang.org/x/crypto v0.54.0/go.mod h1:KWL8ny2AZdGR2cWmzeHrp2azQPGogOv+HeQaVEXC2dk= +golang.org/x/mod v0.37.0 h1:vF1DjpVEshcIqoEaauuHebaLk1O1forxjxBaVn884JQ= +golang.org/x/mod v0.37.0/go.mod h1:m8S8VeM9r4dzDwjrKO0a1sZP3YjeMamRRlD+fmR2Q/0= +golang.org/x/net v0.57.0 h1:K5+3DljvIuDG9/Jv9rvyMywYNFCQ9RSUY6OOTTkT+tE= +golang.org/x/net v0.57.0/go.mod h1:KpXc8iv+r3XplLAG/f7Jsf9RPszJzdR0f58q9vGOuEU= +golang.org/x/sync v0.22.0 h1:SZjpbeLmrCk4xhRSZFNZW5gFUeCeFgjekvI/+gfScek= +golang.org/x/sync v0.22.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= +golang.org/x/sys v0.47.0 h1:o7XGOvZQCADBQQ4Y7VNq2dRWQR7JmOUW8Kxx4ZsNgWs= +golang.org/x/sys v0.47.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/text v0.40.0 h1:Ub2Z6/xjgF1WrYQz2nuITOEegKFtiIy+rieRJ5lHZKs= +golang.org/x/text v0.40.0/go.mod h1:hpnzDAfGV753zIKo+wk3u1bVKCGPbrnF7+7LBF/UHVY= +golang.org/x/tools v0.47.0 h1:7Kn5x/d1svx/PzryTsqeoZN4TZwqeH5pGWjefhLi/1Q= +golang.org/x/tools v0.47.0/go.mod h1:dFHnyTvFWY212G+h7ZY4Vsp/K3U4/7W9TyVaAul8uCA= +gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4= +gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260511170946-3700d4141b60 h1:seT2EwLWM78plQ7wcDfuWBc/4FAEAXDDiaSol4ku4qo= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260511170946-3700d4141b60/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= +google.golang.org/grpc v1.82.0 h1:vguDnZUPjE26w09A63VoxZPnvPjB5Riyc0mkXPFmAIU= +google.golang.org/grpc v1.82.0/go.mod h1:yzTZ1TB1Z3SG+LIYaI+WiE8D5+PZ3ArnrSp8zF3+/ZA= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= 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 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -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.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -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/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= -honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= -rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= -rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= diff --git a/https.go b/https.go index 998f259..62f8c4d 100644 --- a/https.go +++ b/https.go @@ -42,7 +42,7 @@ func newHTTPS(from string, client dnsClient, opts ...httpsOption) *HTTPS { var _ plugin.Handler = (*HTTPS)(nil) // Name implements plugin.Handler. -func (*HTTPS) Name() string { return "https" } +func (*HTTPS) Name() string { return pluginName } // ServeDNS implements plugin.Handler. func (h *HTTPS) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (status int, err error) { diff --git a/https_test.go b/https_test.go index ea8853c..544c111 100644 --- a/https_test.go +++ b/https_test.go @@ -9,6 +9,7 @@ import ( "github.com/coredns/coredns/plugin/test" "github.com/miekg/dns" "github.com/stretchr/testify/require" + "go.uber.org/mock/gomock" ) func newRequestDNSMsg() *dns.Msg { @@ -22,49 +23,30 @@ func newRequestDNSMsg() *dns.Msg { } func TestHTTPS(t *testing.T) { + t.Parallel() + dnsMsg := newRequestDNSMsg() dnsdata, err := dnsMsg.Pack() require.NoError(t, err) - dnsClient := &mockDNSClient{reqBody: dnsdata, t: t} + dnsClient := NewMockdnsClient(gomock.NewController(t)) + dnsClient.EXPECT().Query(gomock.Any(), dnsdata).Return(newExpectedDNSMsg(), nil) h := newHTTPS(".", dnsClient) rec := dnstest.NewRecorder(&test.ResponseWriter{}) status, err := h.ServeDNS(context.Background(), rec, dnsMsg) require.NoError(t, err) require.Equal(t, dns.RcodeSuccess, status) - require.Equal(t, 1, dnsClient.callCount, "dnsClient call count is wrong") require.Equal(t, newExpectedDNSMsg(), rec.Msg) } -type mockDNSClientFunc func(ctx context.Context, dnsreq []byte) (*dns.Msg, error) - -func (f mockDNSClientFunc) Query(ctx context.Context, dnsreq []byte) (*dns.Msg, error) { - return f(ctx, dnsreq) -} - -type mockDNSResponseWriter struct { - dns.ResponseWriter - writeFunc func(*dns.Msg) error -} - -func (w *mockDNSResponseWriter) WriteMsg(msg *dns.Msg) error { - return w.writeFunc(msg) -} - func TestHTTPSMsgPackError(t *testing.T) { + t.Parallel() + dnsMsg := &dns.Msg{MsgHdr: dns.MsgHdr{Rcode: 0xFFFFF}} - dnsClient := mockDNSClientFunc(func(_ context.Context, _ []byte) (result *dns.Msg, err error) { - t.Fatal("dns client must not be called") - return - }) + ctrl := gomock.NewController(t) + dnsClient := NewMockdnsClient(ctrl) h := newHTTPS(".", dnsClient) - w := &mockDNSResponseWriter{ - ResponseWriter: &test.ResponseWriter{}, - writeFunc: func(*dns.Msg) (err error) { - t.Fatal("dns response writer must not be called") - return - }, - } + w := NewMockResponseWriter(ctrl) status, err := h.ServeDNS(context.Background(), w, dnsMsg) require.Error(t, err) @@ -72,18 +54,14 @@ func TestHTTPSMsgPackError(t *testing.T) { } func TestHTTPSDNSClientError(t *testing.T) { + t.Parallel() + dnsMsg := newRequestDNSMsg() - dnsClient := mockDNSClientFunc(func(_ context.Context, _ []byte) (*dns.Msg, error) { - return newExpectedDNSMsg(), errors.New("dns client error") - }) + ctrl := gomock.NewController(t) + dnsClient := NewMockdnsClient(ctrl) + dnsClient.EXPECT().Query(gomock.Any(), gomock.Any()).Return(newExpectedDNSMsg(), errors.New("dns client error")) h := newHTTPS(".", dnsClient) - w := &mockDNSResponseWriter{ - ResponseWriter: &test.ResponseWriter{}, - writeFunc: func(*dns.Msg) (err error) { - t.Fatal("dns response writer must not be called") - return - }, - } + w := NewMockResponseWriter(ctrl) status, err := h.ServeDNS(context.Background(), w, dnsMsg) require.Error(t, err) @@ -91,25 +69,26 @@ func TestHTTPSDNSClientError(t *testing.T) { } func TestHTTPSResponseWriterError(t *testing.T) { + t.Parallel() + dnsMsg := newRequestDNSMsg() - dnsClient := mockDNSClientFunc(func(_ context.Context, _ []byte) (*dns.Msg, error) { - return newExpectedDNSMsg(), nil - }) + ctrl := gomock.NewController(t) + dnsClient := NewMockdnsClient(ctrl) + dnsClient.EXPECT().Query(gomock.Any(), gomock.Any()).Return(newExpectedDNSMsg(), nil) h := newHTTPS(".", dnsClient) - w := &mockDNSResponseWriter{ - ResponseWriter: &test.ResponseWriter{}, - writeFunc: func(*dns.Msg) (err error) { - return errors.New("response writer error") - }, - } + w := NewMockResponseWriter(ctrl) + w.EXPECT().WriteMsg(gomock.Any()).Return(errors.New("response writer error")) _, err := h.ServeDNS(context.Background(), w, dnsMsg) require.Error(t, err) } func TestHTTPSDNSResponseStateNotMatch(t *testing.T) { + t.Parallel() + dnsMsg := newRequestDNSMsg() - dnsClient := mockDNSClientFunc(func(_ context.Context, _ []byte) (*dns.Msg, error) { + dnsClient := NewMockdnsClient(gomock.NewController(t)) + dnsClient.EXPECT().Query(gomock.Any(), gomock.Any()).DoAndReturn(func(context.Context, []byte) (*dns.Msg, error) { result := newExpectedDNSMsg() result.Question[0].Name = "other.domain." return result, nil diff --git a/metrics.go b/metrics.go index d6c623e..44c9b78 100644 --- a/metrics.go +++ b/metrics.go @@ -11,19 +11,19 @@ import ( var ( RequestCount = promauto.NewCounterVec(prometheus.CounterOpts{ Namespace: plugin.Namespace, - Subsystem: "https", + Subsystem: pluginName, Name: "requests_total", Help: "Counter of requests made per upstream.", }, []string{"to"}) RcodeCount = promauto.NewCounterVec(prometheus.CounterOpts{ Namespace: plugin.Namespace, - Subsystem: "https", + Subsystem: pluginName, Name: "responses_total", Help: "Counter of requests made per upstream.", }, []string{"rcode", "to"}) RequestDuration = promauto.NewHistogramVec(prometheus.HistogramOpts{ Namespace: plugin.Namespace, - Subsystem: "https", + Subsystem: pluginName, Name: "request_duration_seconds", Buckets: plugin.TimeBuckets, Help: "Histogram of the time each request took.", diff --git a/mocks_dns_test.go b/mocks_dns_test.go new file mode 100644 index 0000000..8e5344e --- /dev/null +++ b/mocks_dns_test.go @@ -0,0 +1,343 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/miekg/dns (interfaces: ResponseWriter) +// +// Generated by this command: +// +// mockgen -destination mocks_dns_test.go -package https -typed github.com/miekg/dns ResponseWriter +// + +// Package https is a generated GoMock package. +package https + +import ( + net "net" + reflect "reflect" + + dns "github.com/miekg/dns" + gomock "go.uber.org/mock/gomock" +) + +// MockResponseWriter is a mock of ResponseWriter interface. +type MockResponseWriter struct { + ctrl *gomock.Controller + recorder *MockResponseWriterMockRecorder + isgomock struct{} +} + +// MockResponseWriterMockRecorder is the mock recorder for MockResponseWriter. +type MockResponseWriterMockRecorder struct { + mock *MockResponseWriter +} + +// NewMockResponseWriter creates a new mock instance. +func NewMockResponseWriter(ctrl *gomock.Controller) *MockResponseWriter { + mock := &MockResponseWriter{ctrl: ctrl} + mock.recorder = &MockResponseWriterMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockResponseWriter) EXPECT() *MockResponseWriterMockRecorder { + return m.recorder +} + +// Close mocks base method. +func (m *MockResponseWriter) Close() error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Close") + ret0, _ := ret[0].(error) + return ret0 +} + +// Close indicates an expected call of Close. +func (mr *MockResponseWriterMockRecorder) Close() *MockResponseWriterCloseCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockResponseWriter)(nil).Close)) + return &MockResponseWriterCloseCall{Call: call} +} + +// MockResponseWriterCloseCall wrap *gomock.Call +type MockResponseWriterCloseCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockResponseWriterCloseCall) Return(arg0 error) *MockResponseWriterCloseCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockResponseWriterCloseCall) Do(f func() error) *MockResponseWriterCloseCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockResponseWriterCloseCall) DoAndReturn(f func() error) *MockResponseWriterCloseCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// Hijack mocks base method. +func (m *MockResponseWriter) Hijack() { + m.ctrl.T.Helper() + m.ctrl.Call(m, "Hijack") +} + +// Hijack indicates an expected call of Hijack. +func (mr *MockResponseWriterMockRecorder) Hijack() *MockResponseWriterHijackCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Hijack", reflect.TypeOf((*MockResponseWriter)(nil).Hijack)) + return &MockResponseWriterHijackCall{Call: call} +} + +// MockResponseWriterHijackCall wrap *gomock.Call +type MockResponseWriterHijackCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockResponseWriterHijackCall) Return() *MockResponseWriterHijackCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockResponseWriterHijackCall) Do(f func()) *MockResponseWriterHijackCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockResponseWriterHijackCall) DoAndReturn(f func()) *MockResponseWriterHijackCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// LocalAddr mocks base method. +func (m *MockResponseWriter) LocalAddr() net.Addr { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "LocalAddr") + ret0, _ := ret[0].(net.Addr) + return ret0 +} + +// LocalAddr indicates an expected call of LocalAddr. +func (mr *MockResponseWriterMockRecorder) LocalAddr() *MockResponseWriterLocalAddrCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LocalAddr", reflect.TypeOf((*MockResponseWriter)(nil).LocalAddr)) + return &MockResponseWriterLocalAddrCall{Call: call} +} + +// MockResponseWriterLocalAddrCall wrap *gomock.Call +type MockResponseWriterLocalAddrCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockResponseWriterLocalAddrCall) Return(arg0 net.Addr) *MockResponseWriterLocalAddrCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockResponseWriterLocalAddrCall) Do(f func() net.Addr) *MockResponseWriterLocalAddrCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockResponseWriterLocalAddrCall) DoAndReturn(f func() net.Addr) *MockResponseWriterLocalAddrCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// RemoteAddr mocks base method. +func (m *MockResponseWriter) RemoteAddr() net.Addr { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "RemoteAddr") + ret0, _ := ret[0].(net.Addr) + return ret0 +} + +// RemoteAddr indicates an expected call of RemoteAddr. +func (mr *MockResponseWriterMockRecorder) RemoteAddr() *MockResponseWriterRemoteAddrCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoteAddr", reflect.TypeOf((*MockResponseWriter)(nil).RemoteAddr)) + return &MockResponseWriterRemoteAddrCall{Call: call} +} + +// MockResponseWriterRemoteAddrCall wrap *gomock.Call +type MockResponseWriterRemoteAddrCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockResponseWriterRemoteAddrCall) Return(arg0 net.Addr) *MockResponseWriterRemoteAddrCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockResponseWriterRemoteAddrCall) Do(f func() net.Addr) *MockResponseWriterRemoteAddrCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockResponseWriterRemoteAddrCall) DoAndReturn(f func() net.Addr) *MockResponseWriterRemoteAddrCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// TsigStatus mocks base method. +func (m *MockResponseWriter) TsigStatus() error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "TsigStatus") + ret0, _ := ret[0].(error) + return ret0 +} + +// TsigStatus indicates an expected call of TsigStatus. +func (mr *MockResponseWriterMockRecorder) TsigStatus() *MockResponseWriterTsigStatusCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TsigStatus", reflect.TypeOf((*MockResponseWriter)(nil).TsigStatus)) + return &MockResponseWriterTsigStatusCall{Call: call} +} + +// MockResponseWriterTsigStatusCall wrap *gomock.Call +type MockResponseWriterTsigStatusCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockResponseWriterTsigStatusCall) Return(arg0 error) *MockResponseWriterTsigStatusCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockResponseWriterTsigStatusCall) Do(f func() error) *MockResponseWriterTsigStatusCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockResponseWriterTsigStatusCall) DoAndReturn(f func() error) *MockResponseWriterTsigStatusCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// TsigTimersOnly mocks base method. +func (m *MockResponseWriter) TsigTimersOnly(arg0 bool) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "TsigTimersOnly", arg0) +} + +// TsigTimersOnly indicates an expected call of TsigTimersOnly. +func (mr *MockResponseWriterMockRecorder) TsigTimersOnly(arg0 any) *MockResponseWriterTsigTimersOnlyCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TsigTimersOnly", reflect.TypeOf((*MockResponseWriter)(nil).TsigTimersOnly), arg0) + return &MockResponseWriterTsigTimersOnlyCall{Call: call} +} + +// MockResponseWriterTsigTimersOnlyCall wrap *gomock.Call +type MockResponseWriterTsigTimersOnlyCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockResponseWriterTsigTimersOnlyCall) Return() *MockResponseWriterTsigTimersOnlyCall { + c.Call = c.Call.Return() + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockResponseWriterTsigTimersOnlyCall) Do(f func(bool)) *MockResponseWriterTsigTimersOnlyCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockResponseWriterTsigTimersOnlyCall) DoAndReturn(f func(bool)) *MockResponseWriterTsigTimersOnlyCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// Write mocks base method. +func (m *MockResponseWriter) Write(arg0 []byte) (int, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Write", arg0) + ret0, _ := ret[0].(int) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Write indicates an expected call of Write. +func (mr *MockResponseWriterMockRecorder) Write(arg0 any) *MockResponseWriterWriteCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Write", reflect.TypeOf((*MockResponseWriter)(nil).Write), arg0) + return &MockResponseWriterWriteCall{Call: call} +} + +// MockResponseWriterWriteCall wrap *gomock.Call +type MockResponseWriterWriteCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockResponseWriterWriteCall) Return(arg0 int, arg1 error) *MockResponseWriterWriteCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockResponseWriterWriteCall) Do(f func([]byte) (int, error)) *MockResponseWriterWriteCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockResponseWriterWriteCall) DoAndReturn(f func([]byte) (int, error)) *MockResponseWriterWriteCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// WriteMsg mocks base method. +func (m *MockResponseWriter) WriteMsg(arg0 *dns.Msg) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "WriteMsg", arg0) + ret0, _ := ret[0].(error) + return ret0 +} + +// WriteMsg indicates an expected call of WriteMsg. +func (mr *MockResponseWriterMockRecorder) WriteMsg(arg0 any) *MockResponseWriterWriteMsgCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WriteMsg", reflect.TypeOf((*MockResponseWriter)(nil).WriteMsg), arg0) + return &MockResponseWriterWriteMsgCall{Call: call} +} + +// MockResponseWriterWriteMsgCall wrap *gomock.Call +type MockResponseWriterWriteMsgCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockResponseWriterWriteMsgCall) Return(arg0 error) *MockResponseWriterWriteMsgCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockResponseWriterWriteMsgCall) Do(f func(*dns.Msg) error) *MockResponseWriterWriteMsgCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockResponseWriterWriteMsgCall) DoAndReturn(f func(*dns.Msg) error) *MockResponseWriterWriteMsgCall { + c.Call = c.Call.DoAndReturn(f) + return c +} diff --git a/mocks_internal_test.go b/mocks_internal_test.go new file mode 100644 index 0000000..ea8e323 --- /dev/null +++ b/mocks_internal_test.go @@ -0,0 +1,145 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/v-byte-cpu/coredns-https (interfaces: dnsClient,httpRequestDoer) +// +// Generated by this command: +// +// mockgen -destination mocks_internal_test.go -package https -typed . dnsClient,httpRequestDoer +// + +// Package https is a generated GoMock package. +package https + +import ( + context "context" + http "net/http" + reflect "reflect" + + dns "github.com/miekg/dns" + gomock "go.uber.org/mock/gomock" +) + +// MockdnsClient is a mock of dnsClient interface. +type MockdnsClient struct { + ctrl *gomock.Controller + recorder *MockdnsClientMockRecorder + isgomock struct{} +} + +// MockdnsClientMockRecorder is the mock recorder for MockdnsClient. +type MockdnsClientMockRecorder struct { + mock *MockdnsClient +} + +// NewMockdnsClient creates a new mock instance. +func NewMockdnsClient(ctrl *gomock.Controller) *MockdnsClient { + mock := &MockdnsClient{ctrl: ctrl} + mock.recorder = &MockdnsClientMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockdnsClient) EXPECT() *MockdnsClientMockRecorder { + return m.recorder +} + +// Query mocks base method. +func (m *MockdnsClient) Query(ctx context.Context, dnsreq []byte) (*dns.Msg, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Query", ctx, dnsreq) + ret0, _ := ret[0].(*dns.Msg) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Query indicates an expected call of Query. +func (mr *MockdnsClientMockRecorder) Query(ctx, dnsreq any) *MockdnsClientQueryCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Query", reflect.TypeOf((*MockdnsClient)(nil).Query), ctx, dnsreq) + return &MockdnsClientQueryCall{Call: call} +} + +// MockdnsClientQueryCall wrap *gomock.Call +type MockdnsClientQueryCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockdnsClientQueryCall) Return(result *dns.Msg, err error) *MockdnsClientQueryCall { + c.Call = c.Call.Return(result, err) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockdnsClientQueryCall) Do(f func(context.Context, []byte) (*dns.Msg, error)) *MockdnsClientQueryCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockdnsClientQueryCall) DoAndReturn(f func(context.Context, []byte) (*dns.Msg, error)) *MockdnsClientQueryCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// MockhttpRequestDoer is a mock of httpRequestDoer interface. +type MockhttpRequestDoer struct { + ctrl *gomock.Controller + recorder *MockhttpRequestDoerMockRecorder + isgomock struct{} +} + +// MockhttpRequestDoerMockRecorder is the mock recorder for MockhttpRequestDoer. +type MockhttpRequestDoerMockRecorder struct { + mock *MockhttpRequestDoer +} + +// NewMockhttpRequestDoer creates a new mock instance. +func NewMockhttpRequestDoer(ctrl *gomock.Controller) *MockhttpRequestDoer { + mock := &MockhttpRequestDoer{ctrl: ctrl} + mock.recorder = &MockhttpRequestDoerMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockhttpRequestDoer) EXPECT() *MockhttpRequestDoerMockRecorder { + return m.recorder +} + +// Do mocks base method. +func (m *MockhttpRequestDoer) Do(req *http.Request) (*http.Response, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Do", req) + ret0, _ := ret[0].(*http.Response) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Do indicates an expected call of Do. +func (mr *MockhttpRequestDoerMockRecorder) Do(req any) *MockhttpRequestDoerDoCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Do", reflect.TypeOf((*MockhttpRequestDoer)(nil).Do), req) + return &MockhttpRequestDoerDoCall{Call: call} +} + +// MockhttpRequestDoerDoCall wrap *gomock.Call +type MockhttpRequestDoerDoCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockhttpRequestDoerDoCall) Return(arg0 *http.Response, arg1 error) *MockhttpRequestDoerDoCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockhttpRequestDoerDoCall) Do(f func(*http.Request) (*http.Response, error)) *MockhttpRequestDoerDoCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockhttpRequestDoerDoCall) DoAndReturn(f func(*http.Request) (*http.Response, error)) *MockhttpRequestDoerDoCall { + c.Call = c.Call.DoAndReturn(f) + return c +} diff --git a/policy_test.go b/policy_test.go index ec70ec4..6e69f60 100644 --- a/policy_test.go +++ b/policy_test.go @@ -7,6 +7,8 @@ import ( ) func TestRandomPolicy(t *testing.T) { + t.Parallel() + tests := []struct { name string poolLen int @@ -46,6 +48,8 @@ func TestRandomPolicy(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { + t.Parallel() + r := newRandomPolicy() if tt.poolLen < 2 { for i, expected := range tt.expected { @@ -54,7 +58,7 @@ func TestRandomPolicy(t *testing.T) { } } else { result := r.List(tt.poolLen) - require.Equal(t, tt.poolLen, len(result)) + require.Len(t, result, tt.poolLen) // verify all elements visited := make([]bool, tt.poolLen) for i := 0; i < tt.poolLen; i++ { @@ -68,6 +72,8 @@ func TestRandomPolicy(t *testing.T) { } func TestRoundRobinPolicy(t *testing.T) { + t.Parallel() + tests := []struct { name string poolLen int @@ -118,6 +124,8 @@ func TestRoundRobinPolicy(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { + t.Parallel() + r := newRoundRobinPolicy() for i, expected := range tt.expected { result := r.List(len(expected)) @@ -128,6 +136,8 @@ func TestRoundRobinPolicy(t *testing.T) { } func TestSequentialPolicy(t *testing.T) { + t.Parallel() + tests := []struct { name string poolLen int @@ -175,6 +185,8 @@ func TestSequentialPolicy(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { + t.Parallel() + p := newSequentialPolicy() for i, expected := range tt.expected { result := p.List(len(expected)) diff --git a/proxy.go b/proxy.go index 8ced0a6..e45afe1 100644 --- a/proxy.go +++ b/proxy.go @@ -29,6 +29,9 @@ var ( errResponseStatus = errors.New("invalid http response status code") ) +//go:generate go tool mockgen -destination mocks_internal_test.go -package https -typed . dnsClient,httpRequestDoer +//go:generate go tool mockgen -destination mocks_dns_test.go -package https -typed github.com/miekg/dns ResponseWriter + // dnsClient is the client API for DNS service type dnsClient interface { Query(ctx context.Context, dnsreq []byte) (result *dns.Msg, err error) diff --git a/proxy_test.go b/proxy_test.go index e9ee410..29c738b 100644 --- a/proxy_test.go +++ b/proxy_test.go @@ -12,16 +12,11 @@ import ( "github.com/miekg/dns" "github.com/stretchr/testify/require" + "go.uber.org/mock/gomock" ) const upstreamURL = "https://example.com/dns-query" -type mockHTTPClientFunc func(*http.Request) (*http.Response, error) - -func (f mockHTTPClientFunc) Do(req *http.Request) (*http.Response, error) { - return f(req) -} - func newExpectedDNSMsg() *dns.Msg { return &dns.Msg{ MsgHdr: dns.MsgHdr{Response: true}, @@ -49,10 +44,11 @@ func packMsg(t *testing.T, msg *dns.Msg) []byte { } func TestDNSClient(t *testing.T) { - callCount := 0 + t.Parallel() + expectedMsg := newExpectedDNSMsg() - httpClient := mockHTTPClientFunc(func(req *http.Request) (resp *http.Response, err error) { - callCount++ + httpClient := NewMockhttpRequestDoer(gomock.NewController(t)) + httpClient.EXPECT().Do(gomock.Any()).DoAndReturn(func(req *http.Request) (resp *http.Response, err error) { acceptHdrs := req.Header["Accept"] require.NotEmpty(t, acceptHdrs, "Accept header is empty") require.Equal(t, dnsMessageMimeType, acceptHdrs[0], "invalid accept header") @@ -78,18 +74,16 @@ func TestDNSClient(t *testing.T) { result, err := dnsClient.Query(context.Background(), []byte("abc")) require.NoError(t, err) - require.Equal(t, 1, callCount, "invalid http client call count") - require.True(t, result.MsgHdr.Response) - require.Equal(t, len(expectedMsg.Answer), len(result.Answer)) + require.True(t, result.Response) + require.Len(t, result.Answer, len(expectedMsg.Answer)) require.Equal(t, expectedMsg.Answer[0].String(), result.Answer[0].String()) } func TestDNSClientNewRequestError(t *testing.T) { + t.Parallel() + invalidURL := "https://example.com/\t\n" - httpClient := mockHTTPClientFunc(func(req *http.Request) (resp *http.Response, err error) { - t.Fatal("http client must not be called") - return - }) + httpClient := NewMockhttpRequestDoer(gomock.NewController(t)) dnsClient := newDoHDNSClient(httpClient, invalidURL) _, err := dnsClient.Query(context.Background(), []byte("abc")) @@ -97,7 +91,10 @@ func TestDNSClientNewRequestError(t *testing.T) { } func TestDNSClientHttpClientError(t *testing.T) { - httpClient := mockHTTPClientFunc(func(req *http.Request) (resp *http.Response, err error) { + t.Parallel() + + httpClient := NewMockhttpRequestDoer(gomock.NewController(t)) + httpClient.EXPECT().Do(gomock.Any()).DoAndReturn(func(*http.Request) (resp *http.Response, err error) { err = errors.New("http error") resp = &http.Response{ Body: io.NopCloser(bytes.NewReader(packMsg(t, newExpectedDNSMsg()))), @@ -112,7 +109,10 @@ func TestDNSClientHttpClientError(t *testing.T) { } func TestDNSClientHttpStatusError(t *testing.T) { - httpClient := mockHTTPClientFunc(func(req *http.Request) (resp *http.Response, err error) { + t.Parallel() + + httpClient := NewMockhttpRequestDoer(gomock.NewController(t)) + httpClient.EXPECT().Do(gomock.Any()).DoAndReturn(func(*http.Request) (resp *http.Response, err error) { resp = &http.Response{ Body: io.NopCloser(bytes.NewReader(packMsg(t, newExpectedDNSMsg()))), StatusCode: http.StatusInternalServerError, @@ -140,7 +140,10 @@ func (r *errReader) Read(p []byte) (n int, err error) { } func TestDNSClientResponseReadError(t *testing.T) { - httpClient := mockHTTPClientFunc(func(req *http.Request) (resp *http.Response, err error) { + t.Parallel() + + httpClient := NewMockhttpRequestDoer(gomock.NewController(t)) + httpClient.EXPECT().Do(gomock.Any()).DoAndReturn(func(*http.Request) (resp *http.Response, err error) { reader := &errReader{ delegate: bytes.NewReader(packMsg(t, newExpectedDNSMsg())), err: errors.New("io error"), @@ -158,7 +161,10 @@ func TestDNSClientResponseReadError(t *testing.T) { } func TestDNSClientMsgUnpackError(t *testing.T) { - httpClient := mockHTTPClientFunc(func(req *http.Request) (resp *http.Response, err error) { + t.Parallel() + + httpClient := NewMockhttpRequestDoer(gomock.NewController(t)) + httpClient.EXPECT().Do(gomock.Any()).DoAndReturn(func(*http.Request) (resp *http.Response, err error) { resp = &http.Response{ Body: io.NopCloser(strings.NewReader("def")), StatusCode: http.StatusOK, @@ -172,13 +178,16 @@ func TestDNSClientMsgUnpackError(t *testing.T) { } func TestDNSClientLargeResponseError(t *testing.T) { + t.Parallel() + // create large buffer with the correct DNS message at the beginning var buf bytes.Buffer dnsMsg := packMsg(t, newExpectedDNSMsg()) buf.Write(dnsMsg) buf.WriteString(strings.Repeat("a", maxDNSMessageSize)) - httpClient := mockHTTPClientFunc(func(req *http.Request) (resp *http.Response, err error) { + httpClient := NewMockhttpRequestDoer(gomock.NewController(t)) + httpClient.EXPECT().Do(gomock.Any()).DoAndReturn(func(*http.Request) (resp *http.Response, err error) { resp = &http.Response{ Body: io.NopCloser(&buf), StatusCode: http.StatusOK, @@ -191,75 +200,74 @@ func TestDNSClientLargeResponseError(t *testing.T) { require.Error(t, err) } -type mockDNSClient struct { - callCount int - reqBody []byte - t *testing.T - err error -} - -func (c *mockDNSClient) Query(ctx context.Context, dnsreq []byte) (result *dns.Msg, err error) { - c.t.Helper() - c.callCount++ - require.NotNil(c.t, ctx) - require.Equal(c.t, c.reqBody, dnsreq, "invalid request body") - return newExpectedDNSMsg(), c.err -} - func TestLoadBalanceDNSClient(t *testing.T) { - client1 := &mockDNSClient{reqBody: []byte("abc"), t: t} + t.Parallel() + + client1 := NewMockdnsClient(gomock.NewController(t)) + client1.EXPECT().Query(gomock.Any(), []byte("abc")).Return(newExpectedDNSMsg(), nil) clients := []dnsClient{client1} lbClient := newLoadBalanceDNSClient(clients) result, err := lbClient.Query(context.Background(), []byte("abc")) require.NoError(t, err) - require.Equal(t, 1, client1.callCount) require.Equal(t, newExpectedDNSMsg(), result) } func TestLoadBalanceDNSClientError(t *testing.T) { - client1 := &mockDNSClient{reqBody: []byte("abc"), t: t, err: errors.New("client error")} + t.Parallel() + + client1 := NewMockdnsClient(gomock.NewController(t)) + client1.EXPECT().Query(gomock.Any(), []byte("abc")).Return(newExpectedDNSMsg(), errors.New("client error")) clients := []dnsClient{client1} lbClient := newLoadBalanceDNSClient(clients) _, err := lbClient.Query(context.Background(), []byte("abc")) require.Error(t, err) - require.Equal(t, 1, client1.callCount) } func TestLoadBalanceDNSClientRetry(t *testing.T) { - client1 := &mockDNSClient{reqBody: []byte("abc"), t: t, err: errors.New("client error")} - client2 := &mockDNSClient{reqBody: []byte("abc"), t: t} + t.Parallel() + + ctrl := gomock.NewController(t) + client1 := NewMockdnsClient(ctrl) + client2 := NewMockdnsClient(ctrl) + gomock.InOrder( + client1.EXPECT().Query(gomock.Any(), []byte("abc")).Return(newExpectedDNSMsg(), errors.New("client error")), + client2.EXPECT().Query(gomock.Any(), []byte("abc")).Return(newExpectedDNSMsg(), nil), + ) clients := []dnsClient{client1, client2} lbClient := newLoadBalanceDNSClient(clients, withLbPolicy(newSequentialPolicy())) result, err := lbClient.Query(context.Background(), []byte("abc")) require.NoError(t, err) - require.Equal(t, 1, client1.callCount) - require.Equal(t, 1, client2.callCount) require.Equal(t, newExpectedDNSMsg(), result) } func TestLoadBalanceDNSClientPolicy(t *testing.T) { - client1 := &mockDNSClient{reqBody: []byte("abc"), t: t} - client2 := &mockDNSClient{reqBody: []byte("abc"), t: t} + t.Parallel() + + ctrl := gomock.NewController(t) + client1 := NewMockdnsClient(ctrl) + client2 := NewMockdnsClient(ctrl) + gomock.InOrder( + client1.EXPECT().Query(gomock.Any(), []byte("abc")).Return(newExpectedDNSMsg(), nil), + client2.EXPECT().Query(gomock.Any(), []byte("abc")).Return(newExpectedDNSMsg(), nil), + ) clients := []dnsClient{client1, client2} lbClient := newLoadBalanceDNSClient(clients, withLbPolicy(newRoundRobinPolicy())) result, err := lbClient.Query(context.Background(), []byte("abc")) require.NoError(t, err) - require.Equal(t, 1, client1.callCount) - require.Equal(t, 0, client2.callCount) require.Equal(t, newExpectedDNSMsg(), result) result, err = lbClient.Query(context.Background(), []byte("abc")) require.NoError(t, err) - require.Equal(t, 1, client1.callCount) - require.Equal(t, 1, client2.callCount) require.Equal(t, newExpectedDNSMsg(), result) } func TestLoadBalanceDNSClientMaxFails(t *testing.T) { + t.Parallel() + tests := []struct { name string maxFails int @@ -282,8 +290,13 @@ func TestLoadBalanceDNSClientMaxFails(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - client1 := &mockDNSClient{reqBody: []byte("abc"), t: t, err: errors.New("client error")} - client2 := &mockDNSClient{reqBody: []byte("abc"), t: t, err: errors.New("client error")} + t.Parallel() + + ctrl := gomock.NewController(t) + client1 := NewMockdnsClient(ctrl) + client2 := NewMockdnsClient(ctrl) + client1.EXPECT().Query(gomock.Any(), []byte("abc")).Return(newExpectedDNSMsg(), errors.New("client error")).Times(tt.callCountClient1) + client2.EXPECT().Query(gomock.Any(), []byte("abc")).Return(newExpectedDNSMsg(), errors.New("client error")).Times(tt.callCountClient2) clients := []dnsClient{client1, client2} lbClient := newLoadBalanceDNSClient(clients, @@ -293,16 +306,17 @@ func TestLoadBalanceDNSClientMaxFails(t *testing.T) { result, err := lbClient.Query(context.Background(), []byte("abc")) require.Error(t, err) - require.Equal(t, tt.callCountClient1, client1.callCount) - require.Equal(t, tt.callCountClient2, client2.callCount) require.Equal(t, newExpectedDNSMsg(), result) }) } } func TestDefaultNewLoadBalanceDNSClient(t *testing.T) { - client1 := &mockDNSClient{reqBody: []byte("abc"), t: t} - client2 := &mockDNSClient{reqBody: []byte("abc"), t: t} + t.Parallel() + + ctrl := gomock.NewController(t) + client1 := NewMockdnsClient(ctrl) + client2 := NewMockdnsClient(ctrl) clients := []dnsClient{client1, client2} lbClient := newLoadBalanceDNSClient(clients) diff --git a/setup.go b/setup.go index 58c76c0..c2e72a2 100644 --- a/setup.go +++ b/setup.go @@ -12,14 +12,17 @@ import ( pkgtls "github.com/coredns/coredns/plugin/pkg/tls" ) -const maxUpstreams = 15 +const ( + pluginName = "dohproxy" + maxUpstreams = 15 +) -func init() { plugin.Register("https", setup) } +func init() { plugin.Register(pluginName, setup) } func setup(c *caddy.Controller) error { conf, err := parseConfig(c) if err != nil { - return plugin.Error("https", err) + return plugin.Error(pluginName, err) } dnsClient := setupDNSClient(conf) diff --git a/setup_test.go b/setup_test.go index fdfa208..c319a31 100644 --- a/setup_test.go +++ b/setup_test.go @@ -10,6 +10,8 @@ import ( ) func TestParseConfig(t *testing.T) { + t.Parallel() + tests := []struct { name string input string @@ -17,7 +19,7 @@ func TestParseConfig(t *testing.T) { }{ { name: "FromAndOneToURL", - input: "https . example.com/dns-query", + input: "dohproxy . example.com/dns-query", expectedConfig: &httpsConfig{ from: ".", toURLs: []string{"https://example.com/dns-query"}, @@ -25,7 +27,7 @@ func TestParseConfig(t *testing.T) { }, { name: "FromAndTwoToURLs", - input: "https . example.com/dns-query example.org/dns-query", + input: "dohproxy . example.com/dns-query example.org/dns-query", expectedConfig: &httpsConfig{ from: ".", toURLs: []string{"https://example.com/dns-query", "https://example.org/dns-query"}, @@ -33,7 +35,7 @@ func TestParseConfig(t *testing.T) { }, { name: "ExceptProperty", - input: "https . example.com/dns-query {\nexcept domain.com\n}\n", + input: "dohproxy . example.com/dns-query {\nexcept domain.com\n}\n", expectedConfig: &httpsConfig{ from: ".", toURLs: []string{"https://example.com/dns-query"}, @@ -42,7 +44,7 @@ func TestParseConfig(t *testing.T) { }, { name: "ExceptPropertyURL", - input: "https . example.com/dns-query {\nexcept https://domain.com\n}\n", + input: "dohproxy . example.com/dns-query {\nexcept https://domain.com\n}\n", expectedConfig: &httpsConfig{ from: ".", toURLs: []string{"https://example.com/dns-query"}, @@ -51,7 +53,7 @@ func TestParseConfig(t *testing.T) { }, { name: "ExceptPropertyTwoDomains", - input: "https . example.com/dns-query {\nexcept domain1.com domain2.com\n}\n", + input: "dohproxy . example.com/dns-query {\nexcept domain1.com domain2.com\n}\n", expectedConfig: &httpsConfig{ from: ".", toURLs: []string{"https://example.com/dns-query"}, @@ -60,7 +62,7 @@ func TestParseConfig(t *testing.T) { }, { name: "TLSServerNameProperty", - input: "https . 10.1.1.1:853/dns-query {\ntls_servername internal.domain\n}\n", + input: "dohproxy . 10.1.1.1:853/dns-query {\ntls_servername internal.domain\n}\n", expectedConfig: &httpsConfig{ from: ".", toURLs: []string{"https://10.1.1.1:853/dns-query"}, @@ -70,7 +72,7 @@ func TestParseConfig(t *testing.T) { }, { name: "PolicyPropertyRandom", - input: "https . example.com/dns-query {\npolicy random\n}\n", + input: "dohproxy . example.com/dns-query {\npolicy random\n}\n", expectedConfig: &httpsConfig{ from: ".", toURLs: []string{"https://example.com/dns-query"}, @@ -79,7 +81,7 @@ func TestParseConfig(t *testing.T) { }, { name: "PolicyPropertyRoundRobin", - input: "https . example.com/dns-query {\npolicy round_robin\n}\n", + input: "dohproxy . example.com/dns-query {\npolicy round_robin\n}\n", expectedConfig: &httpsConfig{ from: ".", toURLs: []string{"https://example.com/dns-query"}, @@ -88,7 +90,7 @@ func TestParseConfig(t *testing.T) { }, { name: "PolicyPropertySequential", - input: "https . example.com/dns-query {\npolicy sequential\n}\n", + input: "dohproxy . example.com/dns-query {\npolicy sequential\n}\n", expectedConfig: &httpsConfig{ from: ".", toURLs: []string{"https://example.com/dns-query"}, @@ -98,7 +100,9 @@ func TestParseConfig(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - c := caddy.NewTestController("https", tt.input) + t.Parallel() + + c := caddy.NewTestController(pluginName, tt.input) conf, err := parseConfig(c) require.NoError(t, err) require.Equal(t, tt.expectedConfig, conf) @@ -107,8 +111,10 @@ func TestParseConfig(t *testing.T) { } func TestParseConfigTLSProperty(t *testing.T) { - input := "https . example.com/dns-query {\ntls\n}\n" - c := caddy.NewTestController("https", input) + t.Parallel() + + input := "dohproxy . example.com/dns-query {\ntls\n}\n" + c := caddy.NewTestController(pluginName, input) conf, err := parseConfig(c) require.NoError(t, err) require.Equal(t, ".", conf.from) @@ -117,6 +123,8 @@ func TestParseConfigTLSProperty(t *testing.T) { } func TestParseConfigError(t *testing.T) { + t.Parallel() + tests := []struct { name string input string @@ -127,56 +135,58 @@ func TestParseConfigError(t *testing.T) { }, { name: "EmptyFrom", - input: "https", + input: "dohproxy", }, { name: "EmptyToURLs", - input: "https .", + input: "dohproxy .", }, { name: "InvalidToURL", - input: "https . abc:&", + input: "dohproxy . abc:&", }, { name: "TooManyToURLs", - input: "https . " + strings.Repeat("example.com/dns-query ", maxUpstreams+1), + input: "dohproxy . " + strings.Repeat("example.com/dns-query ", maxUpstreams+1), }, { name: "UnknownProperty", - input: "https . example.com/dns-query {\nabc\n}\n", + input: "dohproxy . example.com/dns-query {\nabc\n}\n", }, { name: "ExceptPropertyZeroArgs", - input: "https . example.com/dns-query {\nexcept\n}\n", + input: "dohproxy . example.com/dns-query {\nexcept\n}\n", }, { name: "TLSPropertyTooManyArgs", - input: "https . example.com/dns-query {\ntls abc def ghi qwe\n}\n", + input: "dohproxy . example.com/dns-query {\ntls abc def ghi qwe\n}\n", }, { name: "TLSServerNamePropertyZeroArgs", - input: "https . example.com/dns-query {\ntls_servername\n}\n", + input: "dohproxy . example.com/dns-query {\ntls_servername\n}\n", }, { name: "TLSServerNamePropertyTooManyArgs", - input: "https . example.com/dns-query {\ntls_servername abc.com def.com\n}\n", + input: "dohproxy . example.com/dns-query {\ntls_servername abc.com def.com\n}\n", }, { name: "PolicyPropertyZeroArgs", - input: "https . example.com/dns-query {\npolicy\n}\n", + input: "dohproxy . example.com/dns-query {\npolicy\n}\n", }, { name: "PolicyPropertyTooManyArgs", - input: "https . example.com/dns-query {\npolicy random round_robin\n}\n", + input: "dohproxy . example.com/dns-query {\npolicy random round_robin\n}\n", }, { name: "PolicyPropertyUnknownArg", - input: "https . example.com/dns-query {\npolicy abc\n}\n", + input: "dohproxy . example.com/dns-query {\npolicy abc\n}\n", }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - c := caddy.NewTestController("https", tt.input) + t.Parallel() + + c := caddy.NewTestController(pluginName, tt.input) _, err := parseConfig(c) require.Error(t, err) })